blob: 9afd0d4709351baae7927b676e1d8db62f90c6f8 [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++) {
Steven Valdezcd8470f2017-10-11 12:29:36 -0400163 UniquePtr<SSL_SESSION> session(
164 SSL_SESSION_dup(hs->new_session.get(), SSL_SESSION_INCLUDE_NONAUTH));
165 if (!session) {
David Benjamin1386aad2017-07-19 23:57:40 -0400166 return 0;
David Benjamin794cc592017-03-25 22:24:23 -0500167 }
David Benjamin794cc592017-03-25 22:24:23 -0500168
Steven Valdezcd8470f2017-10-11 12:29:36 -0400169 if (!RAND_bytes((uint8_t *)&session->ticket_age_add, 4)) {
170 return 0;
171 }
172 session->ticket_age_add_valid = 1;
Steven Valdezbe165a22017-10-10 11:45:01 -0400173 if (ssl->cert->enable_early_data) {
Steven Valdezcd8470f2017-10-11 12:29:36 -0400174 session->ticket_max_early_data = kMaxEarlyDataAccepted;
Steven Valdezbe165a22017-10-10 11:45:01 -0400175 }
176
Steven Valdezcd8470f2017-10-11 12:29:36 -0400177 static_assert(kNumTickets < 256, "Too many tickets");
178 uint8_t nonce[] = {static_cast<uint8_t>(i)};
179
David Benjamin1386aad2017-07-19 23:57:40 -0400180 ScopedCBB cbb;
Steven Valdezcd8470f2017-10-11 12:29:36 -0400181 CBB body, nonce_cbb, ticket, extensions;
David Benjamin1386aad2017-07-19 23:57:40 -0400182 if (!ssl->method->init_message(ssl, cbb.get(), &body,
David Benjamin794cc592017-03-25 22:24:23 -0500183 SSL3_MT_NEW_SESSION_TICKET) ||
Steven Valdezcd8470f2017-10-11 12:29:36 -0400184 !CBB_add_u32(&body, session->timeout) ||
185 !CBB_add_u32(&body, session->ticket_age_add) ||
186 (ssl_is_draft21(ssl->version) &&
187 (!CBB_add_u8_length_prefixed(&body, &nonce_cbb) ||
188 !CBB_add_bytes(&nonce_cbb, nonce, sizeof(nonce)))) ||
David Benjamin794cc592017-03-25 22:24:23 -0500189 !CBB_add_u16_length_prefixed(&body, &ticket) ||
Steven Valdezcd8470f2017-10-11 12:29:36 -0400190 !tls13_derive_session_psk(session.get(), nonce) ||
191 !ssl_encrypt_ticket(ssl, &ticket, session.get()) ||
David Benjamin794cc592017-03-25 22:24:23 -0500192 !CBB_add_u16_length_prefixed(&body, &extensions)) {
David Benjamin1386aad2017-07-19 23:57:40 -0400193 return 0;
David Benjamin794cc592017-03-25 22:24:23 -0500194 }
195
Alessandro Ghedini67bb45f2017-03-30 16:33:24 -0500196 if (ssl->cert->enable_early_data) {
David Benjamin794cc592017-03-25 22:24:23 -0500197 CBB early_data_info;
Steven Valdezcd8470f2017-10-11 12:29:36 -0400198 if (!CBB_add_u16(&extensions, ssl_is_draft21(ssl->version)
199 ? TLSEXT_TYPE_early_data
200 : TLSEXT_TYPE_ticket_early_data_info) ||
David Benjamin794cc592017-03-25 22:24:23 -0500201 !CBB_add_u16_length_prefixed(&extensions, &early_data_info) ||
Steven Valdezcd8470f2017-10-11 12:29:36 -0400202 !CBB_add_u32(&early_data_info, session->ticket_max_early_data) ||
David Benjamin794cc592017-03-25 22:24:23 -0500203 !CBB_flush(&extensions)) {
David Benjamin1386aad2017-07-19 23:57:40 -0400204 return 0;
David Benjamin794cc592017-03-25 22:24:23 -0500205 }
206 }
207
David Benjaminc11ea9422017-08-29 16:33:21 -0400208 // Add a fake extension. See draft-davidben-tls-grease-01.
David Benjamin794cc592017-03-25 22:24:23 -0500209 if (!CBB_add_u16(&extensions,
210 ssl_get_grease_value(ssl, ssl_grease_ticket_extension)) ||
211 !CBB_add_u16(&extensions, 0 /* empty */)) {
David Benjamin1386aad2017-07-19 23:57:40 -0400212 return 0;
David Benjamin794cc592017-03-25 22:24:23 -0500213 }
214
David Benjamin1386aad2017-07-19 23:57:40 -0400215 if (!ssl_add_message_cbb(ssl, cbb.get())) {
216 return 0;
David Benjamin794cc592017-03-25 22:24:23 -0500217 }
218 }
219
220 return 1;
David Benjamin794cc592017-03-25 22:24:23 -0500221}
222
David Benjaminc3c88822016-11-14 10:32:04 +0900223static enum ssl_hs_wait_t do_select_parameters(SSL_HANDSHAKE *hs) {
David Benjaminc11ea9422017-08-29 16:33:21 -0400224 // At this point, most ClientHello extensions have already been processed by
225 // the common handshake logic. Resolve the remaining non-PSK parameters.
David Benjaminc3c88822016-11-14 10:32:04 +0900226 SSL *const ssl = hs->ssl;
David Benjamin7934f082017-08-01 16:32:25 -0400227 SSLMessage msg;
228 if (!ssl->method->get_message(ssl, &msg)) {
229 return ssl_hs_read_message;
230 }
David Benjamin731058e2016-12-03 23:15:13 -0500231 SSL_CLIENT_HELLO client_hello;
David Benjamin7934f082017-08-01 16:32:25 -0400232 if (!ssl_client_hello_init(ssl, &client_hello, msg)) {
David Benjamin34202b92016-11-16 19:07:53 +0900233 OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_PARSE_FAILED);
David Benjamind1e3ce12017-10-06 18:31:15 -0400234 ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
David Benjamin34202b92016-11-16 19:07:53 +0900235 return ssl_hs_error;
236 }
237
Steven Valdez520e1222017-06-13 12:45:25 -0400238 OPENSSL_memcpy(hs->session_id, client_hello.session_id,
239 client_hello.session_id_len);
240 hs->session_id_len = client_hello.session_id_len;
241
David Benjaminc11ea9422017-08-29 16:33:21 -0400242 // Negotiate the cipher suite.
David Benjamin45738dd2017-02-09 20:01:26 -0500243 hs->new_cipher = choose_tls13_cipher(ssl, &client_hello);
244 if (hs->new_cipher == NULL) {
David Benjaminf01f42a2016-11-16 19:05:33 +0900245 OPENSSL_PUT_ERROR(SSL, SSL_R_NO_SHARED_CIPHER);
David Benjamind1e3ce12017-10-06 18:31:15 -0400246 ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
David Benjaminf01f42a2016-11-16 19:05:33 +0900247 return ssl_hs_error;
248 }
249
David Benjaminc11ea9422017-08-29 16:33:21 -0400250 // HTTP/2 negotiation depends on the cipher suite, so ALPN negotiation was
251 // deferred. Complete it now.
David Benjamin707af292017-03-10 17:47:18 -0500252 uint8_t alert = SSL_AD_DECODE_ERROR;
253 if (!ssl_negotiate_alpn(hs, &alert, &client_hello)) {
David Benjamind1e3ce12017-10-06 18:31:15 -0400254 ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
David Benjamin707af292017-03-10 17:47:18 -0500255 return ssl_hs_error;
256 }
257
David Benjaminc11ea9422017-08-29 16:33:21 -0400258 // The PRF hash is now known. Set up the key schedule and hash the
259 // ClientHello.
Steven Valdezcd8470f2017-10-11 12:29:36 -0400260 if (!hs->transcript.InitHash(ssl_protocol_version(ssl), hs->new_cipher)) {
261 return ssl_hs_error;
262 }
263
264 if (!ssl_hash_message(hs, msg)) {
Steven Valdez908ac192017-01-12 13:17:07 -0500265 return ssl_hs_error;
266 }
267
David Benjamin707af292017-03-10 17:47:18 -0500268 hs->tls13_state = state_select_session;
269 return ssl_hs_ok;
270}
Steven Valdez908ac192017-01-12 13:17:07 -0500271
David Benjamin707af292017-03-10 17:47:18 -0500272static enum ssl_ticket_aead_result_t select_session(
David Benjamin37af90f2017-07-29 01:42:16 -0400273 SSL_HANDSHAKE *hs, uint8_t *out_alert, UniquePtr<SSL_SESSION> *out_session,
David Benjamin7934f082017-08-01 16:32:25 -0400274 int32_t *out_ticket_age_skew, const SSLMessage &msg,
275 const SSL_CLIENT_HELLO *client_hello) {
David Benjamin707af292017-03-10 17:47:18 -0500276 SSL *const ssl = hs->ssl;
277 *out_session = NULL;
278
David Benjaminc11ea9422017-08-29 16:33:21 -0400279 // Decode the ticket if we agreed on a PSK key exchange mode.
David Benjamin707af292017-03-10 17:47:18 -0500280 CBS pre_shared_key;
281 if (!hs->accept_psk_mode ||
282 !ssl_client_hello_get_extension(client_hello, &pre_shared_key,
283 TLSEXT_TYPE_pre_shared_key)) {
284 return ssl_ticket_aead_ignore_ticket;
285 }
286
David Benjaminc11ea9422017-08-29 16:33:21 -0400287 // Verify that the pre_shared_key extension is the last extension in
288 // ClientHello.
David Benjamin707af292017-03-10 17:47:18 -0500289 if (CBS_data(&pre_shared_key) + CBS_len(&pre_shared_key) !=
290 client_hello->extensions + client_hello->extensions_len) {
291 OPENSSL_PUT_ERROR(SSL, SSL_R_PRE_SHARED_KEY_MUST_BE_LAST);
292 *out_alert = SSL_AD_ILLEGAL_PARAMETER;
293 return ssl_ticket_aead_error;
294 }
295
296 CBS ticket, binders;
297 uint32_t client_ticket_age;
298 if (!ssl_ext_pre_shared_key_parse_clienthello(hs, &ticket, &binders,
299 &client_ticket_age, out_alert,
300 &pre_shared_key)) {
301 return ssl_ticket_aead_error;
302 }
303
David Benjaminc11ea9422017-08-29 16:33:21 -0400304 // TLS 1.3 session tickets are renewed separately as part of the
305 // NewSessionTicket.
David Benjaminfd45ee72017-08-31 14:49:09 -0400306 bool unused_renew;
David Benjamin37af90f2017-07-29 01:42:16 -0400307 UniquePtr<SSL_SESSION> session;
David Benjamin707af292017-03-10 17:47:18 -0500308 enum ssl_ticket_aead_result_t ret =
309 ssl_process_ticket(ssl, &session, &unused_renew, CBS_data(&ticket),
310 CBS_len(&ticket), NULL, 0);
311 switch (ret) {
312 case ssl_ticket_aead_success:
313 break;
314 case ssl_ticket_aead_error:
315 *out_alert = SSL_AD_INTERNAL_ERROR;
316 return ret;
317 default:
318 return ret;
319 }
320
David Benjamin37af90f2017-07-29 01:42:16 -0400321 if (!ssl_session_is_resumable(hs, session.get()) ||
David Benjaminc11ea9422017-08-29 16:33:21 -0400322 // Historically, some TLS 1.3 tickets were missing ticket_age_add.
David Benjamin707af292017-03-10 17:47:18 -0500323 !session->ticket_age_add_valid) {
David Benjamin707af292017-03-10 17:47:18 -0500324 return ssl_ticket_aead_ignore_ticket;
325 }
326
David Benjaminc11ea9422017-08-29 16:33:21 -0400327 // Recover the client ticket age and convert to seconds.
David Benjamin707af292017-03-10 17:47:18 -0500328 client_ticket_age -= session->ticket_age_add;
329 client_ticket_age /= 1000;
330
331 struct OPENSSL_timeval now;
332 ssl_get_current_time(ssl, &now);
333
David Benjaminc11ea9422017-08-29 16:33:21 -0400334 // Compute the server ticket age in seconds.
David Benjamin707af292017-03-10 17:47:18 -0500335 assert(now.tv_sec >= session->time);
336 uint64_t server_ticket_age = now.tv_sec - session->time;
337
David Benjaminc11ea9422017-08-29 16:33:21 -0400338 // To avoid overflowing |hs->ticket_age_skew|, we will not resume
339 // 68-year-old sessions.
David Benjamin707af292017-03-10 17:47:18 -0500340 if (server_ticket_age > INT32_MAX) {
David Benjamin707af292017-03-10 17:47:18 -0500341 return ssl_ticket_aead_ignore_ticket;
342 }
343
David Benjaminc11ea9422017-08-29 16:33:21 -0400344 // TODO(davidben,svaldez): Measure this value to decide on tolerance. For
345 // now, accept all values. https://crbug.com/boringssl/113.
David Benjamin707af292017-03-10 17:47:18 -0500346 *out_ticket_age_skew =
347 (int32_t)client_ticket_age - (int32_t)server_ticket_age;
348
David Benjaminc11ea9422017-08-29 16:33:21 -0400349 // Check the PSK binder.
David Benjamin7934f082017-08-01 16:32:25 -0400350 if (!tls13_verify_psk_binder(hs, session.get(), msg, &binders)) {
David Benjamin707af292017-03-10 17:47:18 -0500351 *out_alert = SSL_AD_DECRYPT_ERROR;
352 return ssl_ticket_aead_error;
353 }
354
David Benjamin37af90f2017-07-29 01:42:16 -0400355 *out_session = std::move(session);
David Benjamin707af292017-03-10 17:47:18 -0500356 return ssl_ticket_aead_success;
357}
358
359static enum ssl_hs_wait_t do_select_session(SSL_HANDSHAKE *hs) {
360 SSL *const ssl = hs->ssl;
David Benjamin7934f082017-08-01 16:32:25 -0400361 SSLMessage msg;
362 if (!ssl->method->get_message(ssl, &msg)) {
363 return ssl_hs_read_message;
364 }
David Benjamin707af292017-03-10 17:47:18 -0500365 SSL_CLIENT_HELLO client_hello;
David Benjamin7934f082017-08-01 16:32:25 -0400366 if (!ssl_client_hello_init(ssl, &client_hello, msg)) {
David Benjamin707af292017-03-10 17:47:18 -0500367 OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_PARSE_FAILED);
David Benjamind1e3ce12017-10-06 18:31:15 -0400368 ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
David Benjamin707af292017-03-10 17:47:18 -0500369 return ssl_hs_error;
370 }
371
David Benjamin4eb95cc2016-11-16 17:08:23 +0900372 uint8_t alert = SSL_AD_DECODE_ERROR;
David Benjamin37af90f2017-07-29 01:42:16 -0400373 UniquePtr<SSL_SESSION> session;
David Benjamin7934f082017-08-01 16:32:25 -0400374 switch (select_session(hs, &alert, &session, &ssl->s3->ticket_age_skew, msg,
David Benjamin707af292017-03-10 17:47:18 -0500375 &client_hello)) {
376 case ssl_ticket_aead_ignore_ticket:
David Benjamin37af90f2017-07-29 01:42:16 -0400377 assert(!session);
David Benjamin707af292017-03-10 17:47:18 -0500378 if (!ssl_get_new_session(hs, 1 /* server */)) {
David Benjamind1e3ce12017-10-06 18:31:15 -0400379 ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
David Benjaminf01f42a2016-11-16 19:05:33 +0900380 return ssl_hs_error;
381 }
David Benjamin707af292017-03-10 17:47:18 -0500382 break;
Steven Valdeza833c352016-11-01 13:39:36 -0400383
David Benjamin707af292017-03-10 17:47:18 -0500384 case ssl_ticket_aead_success:
David Benjaminc11ea9422017-08-29 16:33:21 -0400385 // Carry over authentication information from the previous handshake into
386 // a fresh session.
David Benjamin37af90f2017-07-29 01:42:16 -0400387 hs->new_session =
388 SSL_SESSION_dup(session.get(), SSL_SESSION_DUP_AUTH_ONLY);
Steven Valdez2d850622017-01-11 11:34:52 -0500389
David Benjamin8e7bbba2017-10-13 17:18:35 -0400390 if (ssl->cert->enable_early_data &&
391 // Early data must be acceptable for this ticket.
Steven Valdez2d850622017-01-11 11:34:52 -0500392 session->ticket_max_early_data != 0 &&
David Benjaminc11ea9422017-08-29 16:33:21 -0400393 // The client must have offered early data.
Steven Valdez2d850622017-01-11 11:34:52 -0500394 hs->early_data_offered &&
David Benjaminc11ea9422017-08-29 16:33:21 -0400395 // Channel ID is incompatible with 0-RTT.
Steven Valdez2a070722017-03-25 20:54:16 -0500396 !ssl->s3->tlsext_channel_id_valid &&
David Benjaminc11ea9422017-08-29 16:33:21 -0400397 // Custom extensions is incompatible with 0-RTT.
Steven Valdezf4ecc842017-08-10 14:02:56 -0400398 hs->custom_extensions.received == 0 &&
David Benjaminc11ea9422017-08-29 16:33:21 -0400399 // The negotiated ALPN must match the one in the ticket.
David Benjamin8e7bbba2017-10-13 17:18:35 -0400400 ssl->s3->alpn_selected ==
401 MakeConstSpan(session->early_alpn, session->early_alpn_len)) {
David Benjamin7e58c5e2017-10-11 13:01:08 -0400402 ssl->early_data_accepted = true;
Steven Valdez2d850622017-01-11 11:34:52 -0500403 }
404
David Benjamin707af292017-03-10 17:47:18 -0500405 if (hs->new_session == NULL) {
David Benjamind1e3ce12017-10-06 18:31:15 -0400406 ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
David Benjamin707af292017-03-10 17:47:18 -0500407 return ssl_hs_error;
408 }
409
David Benjamin046bc1f2017-08-31 15:06:42 -0400410 ssl->s3->session_reused = true;
David Benjamin707af292017-03-10 17:47:18 -0500411
David Benjaminc11ea9422017-08-29 16:33:21 -0400412 // Resumption incorporates fresh key material, so refresh the timeout.
David Benjamin31b0c9b2017-07-20 14:49:15 -0400413 ssl_session_renew_timeout(ssl, hs->new_session.get(),
David Benjamin707af292017-03-10 17:47:18 -0500414 ssl->session_ctx->session_psk_dhe_timeout);
415 break;
416
417 case ssl_ticket_aead_error:
David Benjamind1e3ce12017-10-06 18:31:15 -0400418 ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
David Benjamin707af292017-03-10 17:47:18 -0500419 return ssl_hs_error;
420
421 case ssl_ticket_aead_retry:
422 hs->tls13_state = state_select_session;
423 return ssl_hs_pending_ticket;
424 }
425
David Benjaminc11ea9422017-08-29 16:33:21 -0400426 // Record connection properties in the new session.
David Benjamin707af292017-03-10 17:47:18 -0500427 hs->new_session->cipher = hs->new_cipher;
428
David Benjaminc11ea9422017-08-29 16:33:21 -0400429 // Store the initial negotiated ALPN in the session.
David Benjamin8e7bbba2017-10-13 17:18:35 -0400430 if (!ssl->s3->alpn_selected.empty()) {
David Benjamind304a2f2017-07-12 23:00:28 -0400431 hs->new_session->early_alpn = (uint8_t *)BUF_memdup(
David Benjamin8e7bbba2017-10-13 17:18:35 -0400432 ssl->s3->alpn_selected.data(), ssl->s3->alpn_selected.size());
David Benjamin45738dd2017-02-09 20:01:26 -0500433 if (hs->new_session->early_alpn == NULL) {
David Benjamind1e3ce12017-10-06 18:31:15 -0400434 ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
Steven Valdez27a9e6a2017-02-14 13:20:40 -0500435 return ssl_hs_error;
436 }
David Benjamin8e7bbba2017-10-13 17:18:35 -0400437 hs->new_session->early_alpn_len = ssl->s3->alpn_selected.size();
Steven Valdez27a9e6a2017-02-14 13:20:40 -0500438 }
439
David Benjamin707af292017-03-10 17:47:18 -0500440 if (ssl->ctx->dos_protection_cb != NULL &&
441 ssl->ctx->dos_protection_cb(&client_hello) == 0) {
David Benjaminc11ea9422017-08-29 16:33:21 -0400442 // Connection rejected for DOS reasons.
David Benjamin707af292017-03-10 17:47:18 -0500443 OPENSSL_PUT_ERROR(SSL, SSL_R_CONNECTION_REJECTED);
David Benjamind1e3ce12017-10-06 18:31:15 -0400444 ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
David Benjamin707af292017-03-10 17:47:18 -0500445 return ssl_hs_error;
446 }
447
Steven Valdezcd8470f2017-10-11 12:29:36 -0400448 size_t hash_len = EVP_MD_size(
449 ssl_get_handshake_digest(ssl_protocol_version(ssl), hs->new_cipher));
450
451 // Set up the key schedule and incorporate the PSK into the running secret.
David Benjamin8f820b42016-11-30 11:24:40 -0500452 if (ssl->s3->session_reused) {
Steven Valdezcd8470f2017-10-11 12:29:36 -0400453 if (!tls13_init_key_schedule(hs, hs->new_session->master_key,
David Benjamin45738dd2017-02-09 20:01:26 -0500454 hs->new_session->master_key_length)) {
David Benjamin8f820b42016-11-30 11:24:40 -0500455 return ssl_hs_error;
456 }
Steven Valdezcd8470f2017-10-11 12:29:36 -0400457 } else if (!tls13_init_key_schedule(hs, kZeroes, hash_len)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400458 return ssl_hs_error;
459 }
460
Steven Valdez2d850622017-01-11 11:34:52 -0500461 if (ssl->early_data_accepted) {
462 if (!tls13_derive_early_secrets(hs)) {
463 return ssl_hs_error;
464 }
465 } else if (hs->early_data_offered) {
David Benjamin046bc1f2017-08-31 15:06:42 -0400466 ssl->s3->skip_early_data = true;
Steven Valdez2d850622017-01-11 11:34:52 -0500467 }
468
David Benjaminc11ea9422017-08-29 16:33:21 -0400469 // Resolve ECDHE and incorporate it into the secret.
David Benjamin046bc1f2017-08-31 15:06:42 -0400470 bool need_retry;
David Benjamin6e4fc332016-11-17 16:43:08 +0900471 if (!resolve_ecdhe_secret(hs, &need_retry, &client_hello)) {
Steven Valdez5440fe02016-07-18 12:40:30 -0400472 if (need_retry) {
David Benjamin7e58c5e2017-10-11 13:01:08 -0400473 ssl->early_data_accepted = false;
David Benjamin046bc1f2017-08-31 15:06:42 -0400474 ssl->s3->skip_early_data = true;
David Benjamin8f94c312017-08-01 17:35:55 -0400475 ssl->method->next_message(ssl);
Steven Valdezcd8470f2017-10-11 12:29:36 -0400476 if (ssl_is_draft21(ssl->version) &&
477 !hs->transcript.UpdateForHelloRetryRequest()) {
478 return ssl_hs_error;
479 }
David Benjamin3977f302016-12-11 13:30:41 -0500480 hs->tls13_state = state_send_hello_retry_request;
Steven Valdez5440fe02016-07-18 12:40:30 -0400481 return ssl_hs_ok;
Steven Valdez143e8b32016-07-11 13:19:03 -0400482 }
Steven Valdez5440fe02016-07-18 12:40:30 -0400483 return ssl_hs_error;
484 }
Steven Valdez143e8b32016-07-11 13:19:03 -0400485
David Benjamin8f94c312017-08-01 17:35:55 -0400486 ssl->method->next_message(ssl);
David Benjamin3977f302016-12-11 13:30:41 -0500487 hs->tls13_state = state_send_server_hello;
Steven Valdez5440fe02016-07-18 12:40:30 -0400488 return ssl_hs_ok;
489}
Steven Valdez143e8b32016-07-11 13:19:03 -0400490
David Benjaminc3c88822016-11-14 10:32:04 +0900491static enum ssl_hs_wait_t do_send_hello_retry_request(SSL_HANDSHAKE *hs) {
492 SSL *const ssl = hs->ssl;
David Benjamin1386aad2017-07-19 23:57:40 -0400493 ScopedCBB cbb;
494 CBB body, extensions;
Steven Valdez5440fe02016-07-18 12:40:30 -0400495 uint16_t group_id;
David Benjamin1386aad2017-07-19 23:57:40 -0400496 if (!ssl->method->init_message(ssl, cbb.get(), &body,
Steven Valdez5440fe02016-07-18 12:40:30 -0400497 SSL3_MT_HELLO_RETRY_REQUEST) ||
498 !CBB_add_u16(&body, ssl->version) ||
Steven Valdezcd8470f2017-10-11 12:29:36 -0400499 (ssl_is_draft21(ssl->version) &&
500 !CBB_add_u16(&body, ssl_cipher_get_value(hs->new_cipher))) ||
David Benjaminf3c8f8d2016-11-17 17:20:47 +0900501 !tls1_get_shared_group(hs, &group_id) ||
Steven Valdez5440fe02016-07-18 12:40:30 -0400502 !CBB_add_u16_length_prefixed(&body, &extensions) ||
David Benjamin3baa6e12016-10-07 21:10:38 -0400503 !CBB_add_u16(&extensions, TLSEXT_TYPE_key_share) ||
504 !CBB_add_u16(&extensions, 2 /* length */) ||
505 !CBB_add_u16(&extensions, group_id) ||
David Benjamin1386aad2017-07-19 23:57:40 -0400506 !ssl_add_message_cbb(ssl, cbb.get())) {
Steven Valdez5440fe02016-07-18 12:40:30 -0400507 return ssl_hs_error;
508 }
509
David Benjamin7934f082017-08-01 16:32:25 -0400510 hs->tls13_state = state_read_second_client_hello;
511 return ssl_hs_flush;
Steven Valdez5440fe02016-07-18 12:40:30 -0400512}
513
David Benjamin7934f082017-08-01 16:32:25 -0400514static enum ssl_hs_wait_t do_read_second_client_hello(SSL_HANDSHAKE *hs) {
David Benjaminc3c88822016-11-14 10:32:04 +0900515 SSL *const ssl = hs->ssl;
David Benjamin7934f082017-08-01 16:32:25 -0400516 SSLMessage msg;
517 if (!ssl->method->get_message(ssl, &msg)) {
518 return ssl_hs_read_message;
519 }
520 if (!ssl_check_message_type(ssl, msg, SSL3_MT_CLIENT_HELLO)) {
Steven Valdez5440fe02016-07-18 12:40:30 -0400521 return ssl_hs_error;
522 }
David Benjamin731058e2016-12-03 23:15:13 -0500523 SSL_CLIENT_HELLO client_hello;
David Benjamin7934f082017-08-01 16:32:25 -0400524 if (!ssl_client_hello_init(ssl, &client_hello, msg)) {
Steven Valdez5440fe02016-07-18 12:40:30 -0400525 OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_PARSE_FAILED);
David Benjamind1e3ce12017-10-06 18:31:15 -0400526 ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
Steven Valdez5440fe02016-07-18 12:40:30 -0400527 return ssl_hs_error;
528 }
529
David Benjamin046bc1f2017-08-31 15:06:42 -0400530 bool need_retry;
David Benjamin6e4fc332016-11-17 16:43:08 +0900531 if (!resolve_ecdhe_secret(hs, &need_retry, &client_hello)) {
Steven Valdez5440fe02016-07-18 12:40:30 -0400532 if (need_retry) {
David Benjaminc11ea9422017-08-29 16:33:21 -0400533 // Only send one HelloRetryRequest.
David Benjamind1e3ce12017-10-06 18:31:15 -0400534 ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
Steven Valdez5440fe02016-07-18 12:40:30 -0400535 OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CURVE);
Steven Valdez143e8b32016-07-11 13:19:03 -0400536 }
Steven Valdez5440fe02016-07-18 12:40:30 -0400537 return ssl_hs_error;
538 }
539
David Benjamin7934f082017-08-01 16:32:25 -0400540 if (!ssl_hash_message(hs, msg)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400541 return ssl_hs_error;
542 }
543
David Benjamin8f94c312017-08-01 17:35:55 -0400544 ssl->method->next_message(ssl);
David Benjamin3977f302016-12-11 13:30:41 -0500545 hs->tls13_state = state_send_server_hello;
Steven Valdez143e8b32016-07-11 13:19:03 -0400546 return ssl_hs_ok;
547}
548
David Benjaminc3c88822016-11-14 10:32:04 +0900549static enum ssl_hs_wait_t do_send_server_hello(SSL_HANDSHAKE *hs) {
550 SSL *const ssl = hs->ssl;
David Benjamin81b7bc32017-01-12 19:44:57 -0500551
Steven Valdez038da9b2017-07-10 12:57:25 -0400552 uint16_t version = ssl->version;
Steven Valdez16821262017-09-08 17:03:42 -0400553 if (ssl_is_resumption_experiment(ssl->version)) {
Steven Valdez038da9b2017-07-10 12:57:25 -0400554 version = TLS1_2_VERSION;
555 }
556
David Benjaminc11ea9422017-08-29 16:33:21 -0400557 // Send a ServerHello.
David Benjamin1386aad2017-07-19 23:57:40 -0400558 ScopedCBB cbb;
559 CBB body, extensions, session_id;
560 if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_SERVER_HELLO) ||
Steven Valdez038da9b2017-07-10 12:57:25 -0400561 !CBB_add_u16(&body, version) ||
Steven Valdez143e8b32016-07-11 13:19:03 -0400562 !RAND_bytes(ssl->s3->server_random, sizeof(ssl->s3->server_random)) ||
563 !CBB_add_bytes(&body, ssl->s3->server_random, SSL3_RANDOM_SIZE) ||
Steven Valdez16821262017-09-08 17:03:42 -0400564 (ssl_is_resumption_experiment(ssl->version) &&
Steven Valdez520e1222017-06-13 12:45:25 -0400565 (!CBB_add_u8_length_prefixed(&body, &session_id) ||
566 !CBB_add_bytes(&session_id, hs->session_id, hs->session_id_len))) ||
David Benjamin45738dd2017-02-09 20:01:26 -0500567 !CBB_add_u16(&body, ssl_cipher_get_value(hs->new_cipher)) ||
Steven Valdez16821262017-09-08 17:03:42 -0400568 (ssl_is_resumption_experiment(ssl->version) && !CBB_add_u8(&body, 0)) ||
Steven Valdez143e8b32016-07-11 13:19:03 -0400569 !CBB_add_u16_length_prefixed(&body, &extensions) ||
David Benjamin8baf9632016-11-17 17:11:16 +0900570 !ssl_ext_pre_shared_key_add_serverhello(hs, &extensions) ||
Steven Valdez924a3522017-03-02 16:05:03 -0500571 !ssl_ext_key_share_add_serverhello(hs, &extensions) ||
Steven Valdez16821262017-09-08 17:03:42 -0400572 (ssl_is_resumption_experiment(ssl->version) &&
Steven Valdez038da9b2017-07-10 12:57:25 -0400573 !ssl_ext_supported_versions_add_serverhello(hs, &extensions)) ||
David Benjamin1386aad2017-07-19 23:57:40 -0400574 !ssl_add_message_cbb(ssl, cbb.get())) {
575 return ssl_hs_error;
Steven Valdez143e8b32016-07-11 13:19:03 -0400576 }
577
Steven Valdez16821262017-09-08 17:03:42 -0400578 if (ssl_is_resumption_experiment(ssl->version) &&
David Benjamin666d16e2017-10-06 18:45:16 -0400579 !ssl->method->add_change_cipher_spec(ssl)) {
David Benjamin1386aad2017-07-19 23:57:40 -0400580 return ssl_hs_error;
Steven Valdez520e1222017-06-13 12:45:25 -0400581 }
582
David Benjaminc11ea9422017-08-29 16:33:21 -0400583 // Derive and enable the handshake traffic secrets.
Steven Valdez4cb84942016-12-16 11:29:28 -0500584 if (!tls13_derive_handshake_secrets(hs) ||
Steven Valdez4cb84942016-12-16 11:29:28 -0500585 !tls13_set_traffic_key(ssl, evp_aead_seal, hs->server_handshake_secret,
586 hs->hash_len)) {
David Benjamin1386aad2017-07-19 23:57:40 -0400587 return ssl_hs_error;
Steven Valdez143e8b32016-07-11 13:19:03 -0400588 }
589
David Benjaminc11ea9422017-08-29 16:33:21 -0400590 // Send EncryptedExtensions.
David Benjamin1386aad2017-07-19 23:57:40 -0400591 if (!ssl->method->init_message(ssl, cbb.get(), &body,
Steven Valdez143e8b32016-07-11 13:19:03 -0400592 SSL3_MT_ENCRYPTED_EXTENSIONS) ||
David Benjamin8c880a22016-12-03 02:20:34 -0500593 !ssl_add_serverhello_tlsext(hs, &body) ||
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
David Benjaminc3648fa2017-07-01 10:50:56 -0400598 if (!ssl->s3->session_reused) {
David Benjaminc11ea9422017-08-29 16:33:21 -0400599 // Determine whether to request a client certificate.
David Benjaminc3648fa2017-07-01 10:50:56 -0400600 hs->cert_request = !!(ssl->verify_mode & SSL_VERIFY_PEER);
David Benjaminc11ea9422017-08-29 16:33:21 -0400601 // Only request a certificate if Channel ID isn't negotiated.
David Benjaminc3648fa2017-07-01 10:50:56 -0400602 if ((ssl->verify_mode & SSL_VERIFY_PEER_IF_NO_OBC) &&
603 ssl->s3->tlsext_channel_id_valid) {
David Benjaminfd45ee72017-08-31 14:49:09 -0400604 hs->cert_request = false;
David Benjaminc3648fa2017-07-01 10:50:56 -0400605 }
Steven Valdez143e8b32016-07-11 13:19:03 -0400606 }
607
David Benjaminc11ea9422017-08-29 16:33:21 -0400608 // Send a CertificateRequest, if necessary.
David Benjamin81b7bc32017-01-12 19:44:57 -0500609 if (hs->cert_request) {
Steven Valdezcd8470f2017-10-11 12:29:36 -0400610 if (ssl_is_draft21(ssl->version)) {
611 CBB cert_request_extensions, sigalg_contents, sigalgs_cbb;
612 if (!ssl->method->init_message(ssl, cbb.get(), &body,
613 SSL3_MT_CERTIFICATE_REQUEST) ||
614 !CBB_add_u8(&body, 0 /* no certificate_request_context. */) ||
615 !CBB_add_u16_length_prefixed(&body, &cert_request_extensions) ||
616 !CBB_add_u16(&cert_request_extensions,
617 TLSEXT_TYPE_signature_algorithms) ||
618 !CBB_add_u16_length_prefixed(&cert_request_extensions,
619 &sigalg_contents) ||
620 !CBB_add_u16_length_prefixed(&sigalg_contents, &sigalgs_cbb) ||
621 !tls12_add_verify_sigalgs(ssl, &sigalgs_cbb)) {
622 return ssl_hs_error;
623 }
624
625 if (ssl_has_client_CAs(ssl)) {
626 CBB ca_contents;
627 if (!CBB_add_u16(&cert_request_extensions,
628 TLSEXT_TYPE_certificate_authorities) ||
629 !CBB_add_u16_length_prefixed(&cert_request_extensions,
630 &ca_contents) ||
631 !ssl_add_client_CA_list(ssl, &ca_contents) ||
632 !CBB_flush(&cert_request_extensions)) {
633 return ssl_hs_error;
634 }
635 }
636
637 if (!ssl_add_message_cbb(ssl, cbb.get())) {
638 return ssl_hs_error;
639 }
640 } else {
641 CBB sigalgs_cbb;
642 if (!ssl->method->init_message(ssl, cbb.get(), &body,
643 SSL3_MT_CERTIFICATE_REQUEST) ||
644 !CBB_add_u8(&body, 0 /* no certificate_request_context. */) ||
645 !CBB_add_u16_length_prefixed(&body, &sigalgs_cbb) ||
646 !tls12_add_verify_sigalgs(ssl, &sigalgs_cbb) ||
647 !ssl_add_client_CA_list(ssl, &body) ||
648 !CBB_add_u16(&body, 0 /* empty certificate_extensions. */) ||
649 !ssl_add_message_cbb(ssl, cbb.get())) {
650 return ssl_hs_error;
651 }
Steven Valdez143e8b32016-07-11 13:19:03 -0400652 }
653 }
654
David Benjaminc11ea9422017-08-29 16:33:21 -0400655 // Send the server Certificate message, if necessary.
David Benjamin81b7bc32017-01-12 19:44:57 -0500656 if (!ssl->s3->session_reused) {
657 if (!ssl_has_certificate(ssl)) {
658 OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATE_SET);
David Benjamin1386aad2017-07-19 23:57:40 -0400659 return ssl_hs_error;
David Benjamin81b7bc32017-01-12 19:44:57 -0500660 }
661
David Benjamin0f24bed2017-01-12 19:46:50 -0500662 if (!tls13_add_certificate(hs)) {
David Benjamin1386aad2017-07-19 23:57:40 -0400663 return ssl_hs_error;
David Benjamin81b7bc32017-01-12 19:44:57 -0500664 }
665
666 hs->tls13_state = state_send_server_certificate_verify;
667 return ssl_hs_ok;
Steven Valdez143e8b32016-07-11 13:19:03 -0400668 }
669
David Benjamin81b7bc32017-01-12 19:44:57 -0500670 hs->tls13_state = state_send_server_finished;
David Benjamin25ac2512017-01-12 19:31:28 -0500671 return ssl_hs_ok;
Steven Valdez143e8b32016-07-11 13:19:03 -0400672}
673
David Benjamin44148742017-06-17 13:20:59 -0400674static enum ssl_hs_wait_t do_send_server_certificate_verify(SSL_HANDSHAKE *hs) {
675 switch (tls13_add_certificate_verify(hs)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400676 case ssl_private_key_success:
David Benjamin3977f302016-12-11 13:30:41 -0500677 hs->tls13_state = state_send_server_finished;
David Benjamin25ac2512017-01-12 19:31:28 -0500678 return ssl_hs_ok;
Steven Valdez143e8b32016-07-11 13:19:03 -0400679
680 case ssl_private_key_retry:
David Benjamin44148742017-06-17 13:20:59 -0400681 hs->tls13_state = state_send_server_certificate_verify;
Steven Valdez143e8b32016-07-11 13:19:03 -0400682 return ssl_hs_private_key_operation;
683
684 case ssl_private_key_failure:
685 return ssl_hs_error;
686 }
687
688 assert(0);
689 return ssl_hs_error;
690}
691
David Benjaminc3c88822016-11-14 10:32:04 +0900692static enum ssl_hs_wait_t do_send_server_finished(SSL_HANDSHAKE *hs) {
David Benjaminc3c88822016-11-14 10:32:04 +0900693 SSL *const ssl = hs->ssl;
David Benjamin0f24bed2017-01-12 19:46:50 -0500694 if (!tls13_add_finished(hs) ||
David Benjaminc11ea9422017-08-29 16:33:21 -0400695 // Update the secret to the master secret and derive traffic keys.
David Benjamin25ac2512017-01-12 19:31:28 -0500696 !tls13_advance_key_schedule(hs, kZeroes, hs->hash_len) ||
David Benjamin6e4fc332016-11-17 16:43:08 +0900697 !tls13_derive_application_secrets(hs) ||
Steven Valdeza833c352016-11-01 13:39:36 -0400698 !tls13_set_traffic_key(ssl, evp_aead_seal, hs->server_traffic_secret_0,
699 hs->hash_len)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400700 return ssl_hs_error;
701 }
702
David Benjamin794cc592017-03-25 22:24:23 -0500703 if (ssl->early_data_accepted) {
David Benjaminc11ea9422017-08-29 16:33:21 -0400704 // If accepting 0-RTT, we send tickets half-RTT. This gets the tickets on
705 // the wire sooner and also avoids triggering a write on |SSL_read| when
706 // processing the client Finished. This requires computing the client
707 // Finished early. See draft-ietf-tls-tls13-18, section 4.5.1.
Steven Valdezcd8470f2017-10-11 12:29:36 -0400708 if (ssl_is_draft21(ssl->version)) {
709 static const uint8_t kEndOfEarlyData[4] = {SSL3_MT_END_OF_EARLY_DATA, 0,
710 0, 0};
711 if (!hs->transcript.Update(kEndOfEarlyData)) {
712 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
713 return ssl_hs_error;
714 }
715 }
716
David Benjamin794cc592017-03-25 22:24:23 -0500717 size_t finished_len;
718 if (!tls13_finished_mac(hs, hs->expected_client_finished, &finished_len,
719 0 /* client */)) {
720 return ssl_hs_error;
721 }
722
723 if (finished_len != hs->hash_len) {
724 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
725 return ssl_hs_error;
726 }
727
David Benjaminc11ea9422017-08-29 16:33:21 -0400728 // Feed the predicted Finished into the transcript. This allows us to derive
729 // the resumption secret early and send half-RTT tickets.
730 //
731 // TODO(davidben): This will need to be updated for DTLS 1.3.
David Benjamin794cc592017-03-25 22:24:23 -0500732 assert(!SSL_is_dtls(hs->ssl));
David Benjamind304a2f2017-07-12 23:00:28 -0400733 assert(hs->hash_len <= 0xff);
David Benjamin6dc8bf62017-07-19 16:38:21 -0400734 uint8_t header[4] = {SSL3_MT_FINISHED, 0, 0,
735 static_cast<uint8_t>(hs->hash_len)};
David Benjamin75a1f232017-10-11 17:19:19 -0400736 if (!hs->transcript.Update(header) ||
737 !hs->transcript.Update(
738 MakeConstSpan(hs->expected_client_finished, hs->hash_len)) ||
David Benjamin8f94c312017-08-01 17:35:55 -0400739 !tls13_derive_resumption_secret(hs) ||
740 !add_new_session_tickets(hs)) {
David Benjamin794cc592017-03-25 22:24:23 -0500741 return ssl_hs_error;
742 }
743 }
744
Steven Valdez2d850622017-01-11 11:34:52 -0500745 hs->tls13_state = state_read_second_client_flight;
746 return ssl_hs_flush;
747}
748
749static enum ssl_hs_wait_t do_read_second_client_flight(SSL_HANDSHAKE *hs) {
750 SSL *const ssl = hs->ssl;
751 if (ssl->early_data_accepted) {
752 if (!tls13_set_traffic_key(ssl, evp_aead_open, hs->early_traffic_secret,
753 hs->hash_len)) {
754 return ssl_hs_error;
755 }
David Benjaminfd45ee72017-08-31 14:49:09 -0400756 hs->can_early_write = true;
757 hs->can_early_read = true;
758 hs->in_early_data = true;
Steven Valdez2d850622017-01-11 11:34:52 -0500759 hs->tls13_state = state_process_end_of_early_data;
760 return ssl_hs_read_end_of_early_data;
761 }
Steven Valdez2d850622017-01-11 11:34:52 -0500762 hs->tls13_state = state_process_end_of_early_data;
763 return ssl_hs_ok;
764}
765
766static enum ssl_hs_wait_t do_process_end_of_early_data(SSL_HANDSHAKE *hs) {
Steven Valdezcd8470f2017-10-11 12:29:36 -0400767 SSL *const ssl = hs->ssl;
Steven Valdez520e1222017-06-13 12:45:25 -0400768 hs->tls13_state = state_process_change_cipher_spec;
Steven Valdezcd8470f2017-10-11 12:29:36 -0400769 if (hs->early_data_offered) {
770 // If early data was not accepted, the EndOfEarlyData and ChangeCipherSpec
771 // message will be in the discarded early data.
772 if (!hs->ssl->early_data_accepted) {
773 return ssl_hs_ok;
774 }
775 if (ssl_is_draft21(ssl->version)) {
776 SSLMessage msg;
777 if (!ssl->method->get_message(ssl, &msg)) {
778 return ssl_hs_read_message;
779 }
780
781 if (!ssl_check_message_type(ssl, msg, SSL3_MT_END_OF_EARLY_DATA)) {
782 return ssl_hs_error;
783 }
784 if (CBS_len(&msg.body) != 0) {
785 ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
786 OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
787 return ssl_hs_error;
788 }
789 ssl->method->next_message(ssl);
790 }
Steven Valdez520e1222017-06-13 12:45:25 -0400791 }
Steven Valdezc7d4d212017-09-11 13:53:08 -0400792 return ssl_is_resumption_client_ccs_experiment(hs->ssl->version)
Steven Valdez520e1222017-06-13 12:45:25 -0400793 ? ssl_hs_read_change_cipher_spec
794 : ssl_hs_ok;
795}
796
797static enum ssl_hs_wait_t do_process_change_cipher_spec(SSL_HANDSHAKE *hs) {
Steven Valdez2d850622017-01-11 11:34:52 -0500798 SSL *const ssl = hs->ssl;
799 if (!tls13_set_traffic_key(ssl, evp_aead_open, hs->client_handshake_secret,
800 hs->hash_len)) {
801 return ssl_hs_error;
802 }
David Benjamin7934f082017-08-01 16:32:25 -0400803 hs->tls13_state = ssl->early_data_accepted ? state_read_client_finished
804 : state_read_client_certificate;
805 return ssl_hs_ok;
Steven Valdez143e8b32016-07-11 13:19:03 -0400806}
807
David Benjamin7934f082017-08-01 16:32:25 -0400808static enum ssl_hs_wait_t do_read_client_certificate(SSL_HANDSHAKE *hs) {
David Benjaminc3c88822016-11-14 10:32:04 +0900809 SSL *const ssl = hs->ssl;
810 if (!hs->cert_request) {
David Benjaminc11ea9422017-08-29 16:33:21 -0400811 // OpenSSL returns X509_V_OK when no certificates are requested. This is
812 // classed by them as a bug, but it's assumed by at least NGINX.
David Benjamin45738dd2017-02-09 20:01:26 -0500813 hs->new_session->verify_result = X509_V_OK;
Adam Langley37646832016-08-01 16:16:46 -0700814
David Benjaminc11ea9422017-08-29 16:33:21 -0400815 // Skip this state.
David Benjamin7934f082017-08-01 16:32:25 -0400816 hs->tls13_state = state_read_channel_id;
Steven Valdez143e8b32016-07-11 13:19:03 -0400817 return ssl_hs_ok;
818 }
819
David Benjamin4087df92016-08-01 20:16:31 -0400820 const int allow_anonymous =
821 (ssl->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) == 0;
David Benjamin7934f082017-08-01 16:32:25 -0400822 SSLMessage msg;
823 if (!ssl->method->get_message(ssl, &msg)) {
824 return ssl_hs_read_message;
825 }
826 if (!ssl_check_message_type(ssl, msg, SSL3_MT_CERTIFICATE) ||
827 !tls13_process_certificate(hs, msg, allow_anonymous) ||
828 !ssl_hash_message(hs, msg)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400829 return ssl_hs_error;
830 }
831
David Benjamin8f94c312017-08-01 17:35:55 -0400832 ssl->method->next_message(ssl);
David Benjamin7934f082017-08-01 16:32:25 -0400833 hs->tls13_state = state_read_client_certificate_verify;
834 return ssl_hs_ok;
Steven Valdez143e8b32016-07-11 13:19:03 -0400835}
836
David Benjamin7934f082017-08-01 16:32:25 -0400837static enum ssl_hs_wait_t do_read_client_certificate_verify(
David Benjaminc3c88822016-11-14 10:32:04 +0900838 SSL_HANDSHAKE *hs) {
839 SSL *const ssl = hs->ssl;
David Benjamin45738dd2017-02-09 20:01:26 -0500840 if (sk_CRYPTO_BUFFER_num(hs->new_session->certs) == 0) {
David Benjaminc11ea9422017-08-29 16:33:21 -0400841 // Skip this state.
David Benjamin7934f082017-08-01 16:32:25 -0400842 hs->tls13_state = state_read_channel_id;
Steven Valdez143e8b32016-07-11 13:19:03 -0400843 return ssl_hs_ok;
844 }
845
David Benjamin7934f082017-08-01 16:32:25 -0400846 SSLMessage msg;
847 if (!ssl->method->get_message(ssl, &msg)) {
848 return ssl_hs_read_message;
849 }
850
David Benjamin3a1dd462017-07-11 16:13:10 -0400851 switch (ssl_verify_peer_cert(hs)) {
852 case ssl_verify_ok:
853 break;
854 case ssl_verify_invalid:
855 return ssl_hs_error;
856 case ssl_verify_retry:
David Benjamin7934f082017-08-01 16:32:25 -0400857 hs->tls13_state = state_read_client_certificate_verify;
David Benjamin3a1dd462017-07-11 16:13:10 -0400858 return ssl_hs_certificate_verify;
859 }
860
David Benjamin7934f082017-08-01 16:32:25 -0400861 if (!ssl_check_message_type(ssl, msg, SSL3_MT_CERTIFICATE_VERIFY) ||
862 !tls13_process_certificate_verify(hs, msg) ||
863 !ssl_hash_message(hs, msg)) {
David Benjamin6929f272016-11-16 19:10:08 +0900864 return ssl_hs_error;
Steven Valdez143e8b32016-07-11 13:19:03 -0400865 }
866
David Benjamin8f94c312017-08-01 17:35:55 -0400867 ssl->method->next_message(ssl);
David Benjamin7934f082017-08-01 16:32:25 -0400868 hs->tls13_state = state_read_channel_id;
869 return ssl_hs_ok;
Nick Harper60a85cb2016-09-23 16:25:11 -0700870}
871
David Benjamin7934f082017-08-01 16:32:25 -0400872static enum ssl_hs_wait_t do_read_channel_id(SSL_HANDSHAKE *hs) {
David Benjamin8f94c312017-08-01 17:35:55 -0400873 SSL *const ssl = hs->ssl;
874 if (!ssl->s3->tlsext_channel_id_valid) {
David Benjamin7934f082017-08-01 16:32:25 -0400875 hs->tls13_state = state_read_client_finished;
Nick Harper60a85cb2016-09-23 16:25:11 -0700876 return ssl_hs_ok;
877 }
878
David Benjamin7934f082017-08-01 16:32:25 -0400879 SSLMessage msg;
880 if (!ssl->method->get_message(ssl, &msg)) {
881 return ssl_hs_read_message;
882 }
883 if (!ssl_check_message_type(ssl, msg, SSL3_MT_CHANNEL_ID) ||
884 !tls1_verify_channel_id(hs, msg) ||
885 !ssl_hash_message(hs, msg)) {
Nick Harper60a85cb2016-09-23 16:25:11 -0700886 return ssl_hs_error;
887 }
888
David Benjamin8f94c312017-08-01 17:35:55 -0400889 ssl->method->next_message(ssl);
David Benjamin7934f082017-08-01 16:32:25 -0400890 hs->tls13_state = state_read_client_finished;
891 return ssl_hs_ok;
Steven Valdez143e8b32016-07-11 13:19:03 -0400892}
893
David Benjamin7934f082017-08-01 16:32:25 -0400894static enum ssl_hs_wait_t do_read_client_finished(SSL_HANDSHAKE *hs) {
David Benjaminc3c88822016-11-14 10:32:04 +0900895 SSL *const ssl = hs->ssl;
David Benjamin7934f082017-08-01 16:32:25 -0400896 SSLMessage msg;
897 if (!ssl->method->get_message(ssl, &msg)) {
898 return ssl_hs_read_message;
899 }
900 if (!ssl_check_message_type(ssl, msg, SSL3_MT_FINISHED) ||
David Benjaminc11ea9422017-08-29 16:33:21 -0400901 // If early data was accepted, we've already computed the client Finished
902 // and derived the resumption secret.
David Benjamin7934f082017-08-01 16:32:25 -0400903 !tls13_process_finished(hs, msg, ssl->early_data_accepted) ||
David Benjaminc11ea9422017-08-29 16:33:21 -0400904 // evp_aead_seal keys have already been switched.
Steven Valdeza833c352016-11-01 13:39:36 -0400905 !tls13_set_traffic_key(ssl, evp_aead_open, hs->client_traffic_secret_0,
David Benjamin794cc592017-03-25 22:24:23 -0500906 hs->hash_len)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400907 return ssl_hs_error;
908 }
909
David Benjamin794cc592017-03-25 22:24:23 -0500910 if (!ssl->early_data_accepted) {
David Benjamin7934f082017-08-01 16:32:25 -0400911 if (!ssl_hash_message(hs, msg) ||
David Benjamin794cc592017-03-25 22:24:23 -0500912 !tls13_derive_resumption_secret(hs)) {
913 return ssl_hs_error;
914 }
915
David Benjaminc11ea9422017-08-29 16:33:21 -0400916 // We send post-handshake tickets as part of the handshake in 1-RTT.
David Benjamin794cc592017-03-25 22:24:23 -0500917 hs->tls13_state = state_send_new_session_ticket;
David Benjamin8f94c312017-08-01 17:35:55 -0400918 } else {
David Benjaminc11ea9422017-08-29 16:33:21 -0400919 // We already sent half-RTT tickets.
David Benjamin8f94c312017-08-01 17:35:55 -0400920 hs->tls13_state = state_done;
David Benjamin794cc592017-03-25 22:24:23 -0500921 }
922
David Benjamin8f94c312017-08-01 17:35:55 -0400923 ssl->method->next_message(ssl);
Steven Valdez143e8b32016-07-11 13:19:03 -0400924 return ssl_hs_ok;
925}
926
David Benjaminc3c88822016-11-14 10:32:04 +0900927static enum ssl_hs_wait_t do_send_new_session_ticket(SSL_HANDSHAKE *hs) {
David Benjaminc11ea9422017-08-29 16:33:21 -0400928 // If the client doesn't accept resumption with PSK_DHE_KE, don't send a
929 // session ticket.
Steven Valdeza833c352016-11-01 13:39:36 -0400930 if (!hs->accept_psk_mode) {
David Benjamin3977f302016-12-11 13:30:41 -0500931 hs->tls13_state = state_done;
Steven Valdeza833c352016-11-01 13:39:36 -0400932 return ssl_hs_ok;
933 }
934
David Benjamin794cc592017-03-25 22:24:23 -0500935 if (!add_new_session_tickets(hs)) {
936 return ssl_hs_error;
Steven Valdez08b65f42016-12-07 15:29:45 -0500937 }
938
David Benjamin25ac2512017-01-12 19:31:28 -0500939 hs->tls13_state = state_done;
940 return ssl_hs_flush;
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400941}
942
David Benjaminc3c88822016-11-14 10:32:04 +0900943enum ssl_hs_wait_t tls13_server_handshake(SSL_HANDSHAKE *hs) {
David Benjamin3977f302016-12-11 13:30:41 -0500944 while (hs->tls13_state != state_done) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400945 enum ssl_hs_wait_t ret = ssl_hs_error;
David Benjamind304a2f2017-07-12 23:00:28 -0400946 enum server_hs_state_t state =
947 static_cast<enum server_hs_state_t>(hs->tls13_state);
Steven Valdez143e8b32016-07-11 13:19:03 -0400948 switch (state) {
David Benjamin25fe85b2016-08-09 20:00:32 -0400949 case state_select_parameters:
David Benjaminc3c88822016-11-14 10:32:04 +0900950 ret = do_select_parameters(hs);
David Benjamin25fe85b2016-08-09 20:00:32 -0400951 break;
David Benjamin707af292017-03-10 17:47:18 -0500952 case state_select_session:
953 ret = do_select_session(hs);
954 break;
Steven Valdez5440fe02016-07-18 12:40:30 -0400955 case state_send_hello_retry_request:
David Benjaminc3c88822016-11-14 10:32:04 +0900956 ret = do_send_hello_retry_request(hs);
Steven Valdez5440fe02016-07-18 12:40:30 -0400957 break;
David Benjamin7934f082017-08-01 16:32:25 -0400958 case state_read_second_client_hello:
959 ret = do_read_second_client_hello(hs);
Steven Valdez5440fe02016-07-18 12:40:30 -0400960 break;
Steven Valdez143e8b32016-07-11 13:19:03 -0400961 case state_send_server_hello:
David Benjaminc3c88822016-11-14 10:32:04 +0900962 ret = do_send_server_hello(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400963 break;
Steven Valdez143e8b32016-07-11 13:19:03 -0400964 case state_send_server_certificate_verify:
David Benjamin44148742017-06-17 13:20:59 -0400965 ret = do_send_server_certificate_verify(hs);
Steven Valdez2d850622017-01-11 11:34:52 -0500966 break;
Steven Valdez143e8b32016-07-11 13:19:03 -0400967 case state_send_server_finished:
David Benjaminc3c88822016-11-14 10:32:04 +0900968 ret = do_send_server_finished(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400969 break;
Steven Valdez2d850622017-01-11 11:34:52 -0500970 case state_read_second_client_flight:
971 ret = do_read_second_client_flight(hs);
972 break;
973 case state_process_end_of_early_data:
974 ret = do_process_end_of_early_data(hs);
975 break;
Steven Valdez520e1222017-06-13 12:45:25 -0400976 case state_process_change_cipher_spec:
977 ret = do_process_change_cipher_spec(hs);
978 break;
David Benjamin7934f082017-08-01 16:32:25 -0400979 case state_read_client_certificate:
980 ret = do_read_client_certificate(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400981 break;
David Benjamin7934f082017-08-01 16:32:25 -0400982 case state_read_client_certificate_verify:
983 ret = do_read_client_certificate_verify(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400984 break;
David Benjamin7934f082017-08-01 16:32:25 -0400985 case state_read_channel_id:
986 ret = do_read_channel_id(hs);
Nick Harper60a85cb2016-09-23 16:25:11 -0700987 break;
David Benjamin7934f082017-08-01 16:32:25 -0400988 case state_read_client_finished:
989 ret = do_read_client_finished(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400990 break;
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400991 case state_send_new_session_ticket:
David Benjaminc3c88822016-11-14 10:32:04 +0900992 ret = do_send_new_session_ticket(hs);
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400993 break;
Steven Valdez143e8b32016-07-11 13:19:03 -0400994 case state_done:
995 ret = ssl_hs_ok;
996 break;
997 }
998
Steven Valdez4d71a9a2017-08-14 15:08:34 -0400999 if (hs->tls13_state != state) {
David Benjaminf60bcfb2017-08-18 15:23:44 -04001000 ssl_do_info_callback(hs->ssl, SSL_CB_ACCEPT_LOOP, 1);
1001 }
1002
Steven Valdez143e8b32016-07-11 13:19:03 -04001003 if (ret != ssl_hs_ok) {
1004 return ret;
1005 }
1006 }
1007
1008 return ssl_hs_ok;
1009}
David Benjamin86e95b82017-07-18 16:34:25 -04001010
David Benjaminf60bcfb2017-08-18 15:23:44 -04001011const char *tls13_server_handshake_state(SSL_HANDSHAKE *hs) {
1012 enum server_hs_state_t state =
1013 static_cast<enum server_hs_state_t>(hs->tls13_state);
1014 switch (state) {
1015 case state_select_parameters:
1016 return "TLS 1.3 server select_parameters";
1017 case state_select_session:
1018 return "TLS 1.3 server select_session";
1019 case state_send_hello_retry_request:
1020 return "TLS 1.3 server send_hello_retry_request";
1021 case state_read_second_client_hello:
1022 return "TLS 1.3 server read_second_client_hello";
1023 case state_send_server_hello:
1024 return "TLS 1.3 server send_server_hello";
1025 case state_send_server_certificate_verify:
1026 return "TLS 1.3 server send_server_certificate_verify";
1027 case state_send_server_finished:
1028 return "TLS 1.3 server send_server_finished";
1029 case state_read_second_client_flight:
1030 return "TLS 1.3 server read_second_client_flight";
1031 case state_process_change_cipher_spec:
1032 return "TLS 1.3 server process_change_cipher_spec";
1033 case state_process_end_of_early_data:
1034 return "TLS 1.3 server process_end_of_early_data";
1035 case state_read_client_certificate:
1036 return "TLS 1.3 server read_client_certificate";
1037 case state_read_client_certificate_verify:
1038 return "TLS 1.3 server read_client_certificate_verify";
1039 case state_read_channel_id:
1040 return "TLS 1.3 server read_channel_id";
1041 case state_read_client_finished:
1042 return "TLS 1.3 server read_client_finished";
1043 case state_send_new_session_ticket:
1044 return "TLS 1.3 server send_new_session_ticket";
1045 case state_done:
1046 return "TLS 1.3 server done";
1047 }
1048
1049 return "TLS 1.3 server unknown";
1050}
1051
David Benjamin86e95b82017-07-18 16:34:25 -04001052} // namespace bssl