blob: 9c8d1a15da3e091b682600e71a44d8869ae6fc2a [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
15#include <openssl/ssl.h>
16
17#include <assert.h>
18#include <string.h>
19
David Benjaminabbbee12016-10-31 19:20:42 -040020#include <openssl/aead.h>
Steven Valdez143e8b32016-07-11 13:19:03 -040021#include <openssl/bytestring.h>
22#include <openssl/digest.h>
23#include <openssl/err.h>
24#include <openssl/mem.h>
25#include <openssl/rand.h>
26#include <openssl/stack.h>
27
David Benjamin17cf2cb2016-12-13 01:07:13 -050028#include "../crypto/internal.h"
Steven Valdez143e8b32016-07-11 13:19:03 -040029#include "internal.h"
30
31
Steven Valdez08b65f42016-12-07 15:29:45 -050032/* kMaxEarlyDataAccepted is the advertised number of plaintext bytes of early
33 * data that will be accepted. This value should be slightly below
34 * kMaxEarlyDataSkipped in tls_record.c, which is measured in ciphertext. */
35static const size_t kMaxEarlyDataAccepted = 14336;
36
Steven Valdez143e8b32016-07-11 13:19:03 -040037enum server_hs_state_t {
David Benjamindaa05392017-02-02 23:33:21 -050038 state_select_parameters = 0,
David Benjamin707af292017-03-10 17:47:18 -050039 state_select_session,
Steven Valdez5440fe02016-07-18 12:40:30 -040040 state_send_hello_retry_request,
Steven Valdez5440fe02016-07-18 12:40:30 -040041 state_process_second_client_hello,
Steven Valdez143e8b32016-07-11 13:19:03 -040042 state_send_server_hello,
Steven Valdez143e8b32016-07-11 13:19:03 -040043 state_send_server_certificate_verify,
44 state_complete_server_certificate_verify,
45 state_send_server_finished,
Steven Valdez143e8b32016-07-11 13:19:03 -040046 state_process_client_certificate,
47 state_process_client_certificate_verify,
Nick Harper60a85cb2016-09-23 16:25:11 -070048 state_process_channel_id,
Steven Valdez143e8b32016-07-11 13:19:03 -040049 state_process_client_finished,
Steven Valdez1e6f11a2016-07-27 11:10:52 -040050 state_send_new_session_ticket,
Steven Valdez143e8b32016-07-11 13:19:03 -040051 state_done,
52};
53
Steven Valdez5440fe02016-07-18 12:40:30 -040054static const uint8_t kZeroes[EVP_MAX_MD_SIZE] = {0};
55
David Benjamin6e4fc332016-11-17 16:43:08 +090056static int resolve_ecdhe_secret(SSL_HANDSHAKE *hs, int *out_need_retry,
David Benjamin731058e2016-12-03 23:15:13 -050057 SSL_CLIENT_HELLO *client_hello) {
David Benjamin6e4fc332016-11-17 16:43:08 +090058 SSL *const ssl = hs->ssl;
Steven Valdez5440fe02016-07-18 12:40:30 -040059 *out_need_retry = 0;
Steven Valdez5440fe02016-07-18 12:40:30 -040060
Steven Valdez803c77a2016-09-06 14:13:43 -040061 /* We only support connections that include an ECDHE key exchange. */
Steven Valdez5440fe02016-07-18 12:40:30 -040062 CBS key_share;
David Benjamin731058e2016-12-03 23:15:13 -050063 if (!ssl_client_hello_get_extension(client_hello, &key_share,
64 TLSEXT_TYPE_key_share)) {
Steven Valdez5440fe02016-07-18 12:40:30 -040065 OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_KEY_SHARE);
66 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_MISSING_EXTENSION);
David Benjamin6929f272016-11-16 19:10:08 +090067 return 0;
Steven Valdez5440fe02016-07-18 12:40:30 -040068 }
69
Steven Valdez5440fe02016-07-18 12:40:30 -040070 int found_key_share;
71 uint8_t *dhe_secret;
72 size_t dhe_secret_len;
David Benjamin7e1f9842016-09-20 19:24:40 -040073 uint8_t alert = SSL_AD_DECODE_ERROR;
David Benjamin8baf9632016-11-17 17:11:16 +090074 if (!ssl_ext_key_share_parse_clienthello(hs, &found_key_share, &dhe_secret,
Steven Valdez7259f2f2016-08-02 16:55:05 -040075 &dhe_secret_len, &alert,
76 &key_share)) {
Steven Valdez5440fe02016-07-18 12:40:30 -040077 ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
78 return 0;
79 }
80
81 if (!found_key_share) {
82 *out_need_retry = 1;
83 return 0;
84 }
85
David Benjamin6e4fc332016-11-17 16:43:08 +090086 int ok = tls13_advance_key_schedule(hs, dhe_secret, dhe_secret_len);
Steven Valdez5440fe02016-07-18 12:40:30 -040087 OPENSSL_free(dhe_secret);
88 return ok;
89}
90
David Benjamin34202b92016-11-16 19:07:53 +090091static const SSL_CIPHER *choose_tls13_cipher(
David Benjamin731058e2016-12-03 23:15:13 -050092 const SSL *ssl, const SSL_CLIENT_HELLO *client_hello) {
David Benjamin34202b92016-11-16 19:07:53 +090093 if (client_hello->cipher_suites_len % 2 != 0) {
94 return NULL;
95 }
96
97 CBS cipher_suites;
98 CBS_init(&cipher_suites, client_hello->cipher_suites,
99 client_hello->cipher_suites_len);
100
101 const int aes_is_fine = EVP_has_aes_hardware();
David Benjaminf01f42a2016-11-16 19:05:33 +0900102 const uint16_t version = ssl3_protocol_version(ssl);
David Benjamin34202b92016-11-16 19:07:53 +0900103
104 const SSL_CIPHER *best = NULL;
105 while (CBS_len(&cipher_suites) > 0) {
106 uint16_t cipher_suite;
107 if (!CBS_get_u16(&cipher_suites, &cipher_suite)) {
108 return NULL;
109 }
110
David Benjaminf01f42a2016-11-16 19:05:33 +0900111 /* Limit to TLS 1.3 ciphers we know about. */
David Benjamin34202b92016-11-16 19:07:53 +0900112 const SSL_CIPHER *candidate = SSL_get_cipher_by_value(cipher_suite);
David Benjaminf01f42a2016-11-16 19:05:33 +0900113 if (candidate == NULL ||
114 SSL_CIPHER_get_min_version(candidate) > version ||
115 SSL_CIPHER_get_max_version(candidate) < version) {
David Benjamin34202b92016-11-16 19:07:53 +0900116 continue;
117 }
118
119 /* TLS 1.3 removes legacy ciphers, so honor the client order, but prefer
120 * ChaCha20 if we do not have AES hardware. */
121 if (aes_is_fine) {
122 return candidate;
123 }
124
125 if (candidate->algorithm_enc == SSL_CHACHA20POLY1305) {
126 return candidate;
127 }
128
129 if (best == NULL) {
130 best = candidate;
131 }
132 }
133
134 return best;
135}
136
David Benjaminc3c88822016-11-14 10:32:04 +0900137static enum ssl_hs_wait_t do_select_parameters(SSL_HANDSHAKE *hs) {
David Benjamin707af292017-03-10 17:47:18 -0500138 /* At this point, most ClientHello extensions have already been processed by
139 * the common handshake logic. Resolve the remaining non-PSK parameters. */
David Benjaminc3c88822016-11-14 10:32:04 +0900140 SSL *const ssl = hs->ssl;
David Benjamin650aa1c2016-12-20 18:55:16 -0500141
David Benjamin731058e2016-12-03 23:15:13 -0500142 SSL_CLIENT_HELLO client_hello;
143 if (!ssl_client_hello_init(ssl, &client_hello, ssl->init_msg,
144 ssl->init_num)) {
David Benjamin34202b92016-11-16 19:07:53 +0900145 OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_PARSE_FAILED);
146 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
147 return ssl_hs_error;
148 }
149
David Benjaminf01f42a2016-11-16 19:05:33 +0900150 /* Negotiate the cipher suite. */
David Benjamin45738dd2017-02-09 20:01:26 -0500151 hs->new_cipher = choose_tls13_cipher(ssl, &client_hello);
152 if (hs->new_cipher == NULL) {
David Benjaminf01f42a2016-11-16 19:05:33 +0900153 OPENSSL_PUT_ERROR(SSL, SSL_R_NO_SHARED_CIPHER);
154 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
155 return ssl_hs_error;
156 }
157
David Benjamin707af292017-03-10 17:47:18 -0500158 /* HTTP/2 negotiation depends on the cipher suite, so ALPN negotiation was
159 * deferred. Complete it now. */
160 uint8_t alert = SSL_AD_DECODE_ERROR;
161 if (!ssl_negotiate_alpn(hs, &alert, &client_hello)) {
162 ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
163 return ssl_hs_error;
164 }
165
Steven Valdez908ac192017-01-12 13:17:07 -0500166 /* The PRF hash is now known. Set up the key schedule and hash the
167 * ClientHello. */
168 if (!tls13_init_key_schedule(hs) ||
169 !ssl_hash_current_message(hs)) {
170 return ssl_hs_error;
171 }
172
David Benjamin707af292017-03-10 17:47:18 -0500173 hs->tls13_state = state_select_session;
174 return ssl_hs_ok;
175}
Steven Valdez908ac192017-01-12 13:17:07 -0500176
David Benjamin707af292017-03-10 17:47:18 -0500177static enum ssl_ticket_aead_result_t select_session(
178 SSL_HANDSHAKE *hs, uint8_t *out_alert, SSL_SESSION **out_session,
179 int32_t *out_ticket_age_skew, const SSL_CLIENT_HELLO *client_hello) {
180 SSL *const ssl = hs->ssl;
181 *out_session = NULL;
182
183 /* Decode the ticket if we agreed on a PSK key exchange mode. */
184 CBS pre_shared_key;
185 if (!hs->accept_psk_mode ||
186 !ssl_client_hello_get_extension(client_hello, &pre_shared_key,
187 TLSEXT_TYPE_pre_shared_key)) {
188 return ssl_ticket_aead_ignore_ticket;
189 }
190
191 /* Verify that the pre_shared_key extension is the last extension in
192 * ClientHello. */
193 if (CBS_data(&pre_shared_key) + CBS_len(&pre_shared_key) !=
194 client_hello->extensions + client_hello->extensions_len) {
195 OPENSSL_PUT_ERROR(SSL, SSL_R_PRE_SHARED_KEY_MUST_BE_LAST);
196 *out_alert = SSL_AD_ILLEGAL_PARAMETER;
197 return ssl_ticket_aead_error;
198 }
199
200 CBS ticket, binders;
201 uint32_t client_ticket_age;
202 if (!ssl_ext_pre_shared_key_parse_clienthello(hs, &ticket, &binders,
203 &client_ticket_age, out_alert,
204 &pre_shared_key)) {
205 return ssl_ticket_aead_error;
206 }
207
208 /* TLS 1.3 session tickets are renewed separately as part of the
209 * NewSessionTicket. */
210 int unused_renew;
211 SSL_SESSION *session = NULL;
212 enum ssl_ticket_aead_result_t ret =
213 ssl_process_ticket(ssl, &session, &unused_renew, CBS_data(&ticket),
214 CBS_len(&ticket), NULL, 0);
215 switch (ret) {
216 case ssl_ticket_aead_success:
217 break;
218 case ssl_ticket_aead_error:
219 *out_alert = SSL_AD_INTERNAL_ERROR;
220 return ret;
221 default:
222 return ret;
223 }
224
225 if (!ssl_session_is_resumable(hs, session) ||
226 /* Historically, some TLS 1.3 tickets were missing ticket_age_add. */
227 !session->ticket_age_add_valid) {
228 SSL_SESSION_free(session);
229 return ssl_ticket_aead_ignore_ticket;
230 }
231
232 /* Recover the client ticket age and convert to seconds. */
233 client_ticket_age -= session->ticket_age_add;
234 client_ticket_age /= 1000;
235
236 struct OPENSSL_timeval now;
237 ssl_get_current_time(ssl, &now);
238
239 /* Compute the server ticket age in seconds. */
240 assert(now.tv_sec >= session->time);
241 uint64_t server_ticket_age = now.tv_sec - session->time;
242
243 /* To avoid overflowing |hs->ticket_age_skew|, we will not resume
244 * 68-year-old sessions. */
245 if (server_ticket_age > INT32_MAX) {
246 SSL_SESSION_free(session);
247 return ssl_ticket_aead_ignore_ticket;
248 }
249
250 /* TODO(davidben,svaldez): Measure this value to decide on tolerance. For
251 * now, accept all values. https://crbug.com/boringssl/113. */
252 *out_ticket_age_skew =
253 (int32_t)client_ticket_age - (int32_t)server_ticket_age;
254
255 /* Check the PSK binder. */
256 if (!tls13_verify_psk_binder(hs, session, &binders)) {
257 SSL_SESSION_free(session);
258 *out_alert = SSL_AD_DECRYPT_ERROR;
259 return ssl_ticket_aead_error;
260 }
261
262 *out_session = session;
263 return ssl_ticket_aead_success;
264}
265
266static enum ssl_hs_wait_t do_select_session(SSL_HANDSHAKE *hs) {
267 SSL *const ssl = hs->ssl;
268 SSL_CLIENT_HELLO client_hello;
269 if (!ssl_client_hello_init(ssl, &client_hello, ssl->init_msg,
270 ssl->init_num)) {
271 OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_PARSE_FAILED);
272 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
273 return ssl_hs_error;
274 }
275
David Benjamin4eb95cc2016-11-16 17:08:23 +0900276 uint8_t alert = SSL_AD_DECODE_ERROR;
277 SSL_SESSION *session = NULL;
David Benjamin707af292017-03-10 17:47:18 -0500278 switch (select_session(hs, &alert, &session, &ssl->s3->ticket_age_skew,
279 &client_hello)) {
280 case ssl_ticket_aead_ignore_ticket:
281 assert(session == NULL);
282 if (!ssl_get_new_session(hs, 1 /* server */)) {
David Benjaminf01f42a2016-11-16 19:05:33 +0900283 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
284 return ssl_hs_error;
285 }
David Benjamin707af292017-03-10 17:47:18 -0500286 break;
Steven Valdeza833c352016-11-01 13:39:36 -0400287
David Benjamin707af292017-03-10 17:47:18 -0500288 case ssl_ticket_aead_success:
289 /* Carry over authentication information from the previous handshake into
290 * a fresh session. */
291 hs->new_session = SSL_SESSION_dup(session, SSL_SESSION_DUP_AUTH_ONLY);
292 SSL_SESSION_free(session);
293 if (hs->new_session == NULL) {
294 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
295 return ssl_hs_error;
296 }
297
298 ssl->s3->session_reused = 1;
299
300 /* Resumption incorporates fresh key material, so refresh the timeout. */
301 ssl_session_renew_timeout(ssl, hs->new_session,
302 ssl->session_ctx->session_psk_dhe_timeout);
303 break;
304
305 case ssl_ticket_aead_error:
306 ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
307 return ssl_hs_error;
308
309 case ssl_ticket_aead_retry:
310 hs->tls13_state = state_select_session;
311 return ssl_hs_pending_ticket;
312 }
313
314 /* Record connection properties in the new session. */
315 hs->new_session->cipher = hs->new_cipher;
316
317 if (hs->hostname != NULL) {
318 OPENSSL_free(hs->new_session->tlsext_hostname);
319 hs->new_session->tlsext_hostname = BUF_strdup(hs->hostname);
320 if (hs->new_session->tlsext_hostname == NULL) {
Steven Valdez4aa154e2016-07-29 14:32:55 -0400321 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
322 return ssl_hs_error;
323 }
Steven Valdez143e8b32016-07-11 13:19:03 -0400324 }
325
Steven Valdez27a9e6a2017-02-14 13:20:40 -0500326 if (ssl->s3->alpn_selected != NULL) {
David Benjamin45738dd2017-02-09 20:01:26 -0500327 hs->new_session->early_alpn =
Steven Valdez27a9e6a2017-02-14 13:20:40 -0500328 BUF_memdup(ssl->s3->alpn_selected, ssl->s3->alpn_selected_len);
David Benjamin45738dd2017-02-09 20:01:26 -0500329 if (hs->new_session->early_alpn == NULL) {
Steven Valdez27a9e6a2017-02-14 13:20:40 -0500330 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
331 return ssl_hs_error;
332 }
David Benjamin45738dd2017-02-09 20:01:26 -0500333 hs->new_session->early_alpn_len = ssl->s3->alpn_selected_len;
Steven Valdez27a9e6a2017-02-14 13:20:40 -0500334 }
335
David Benjamin707af292017-03-10 17:47:18 -0500336 if (ssl->ctx->dos_protection_cb != NULL &&
337 ssl->ctx->dos_protection_cb(&client_hello) == 0) {
338 /* Connection rejected for DOS reasons. */
339 OPENSSL_PUT_ERROR(SSL, SSL_R_CONNECTION_REJECTED);
340 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
341 return ssl_hs_error;
342 }
343
David Benjamin8f820b42016-11-30 11:24:40 -0500344 /* Incorporate the PSK into the running secret. */
345 if (ssl->s3->session_reused) {
David Benjamin45738dd2017-02-09 20:01:26 -0500346 if (!tls13_advance_key_schedule(hs, hs->new_session->master_key,
347 hs->new_session->master_key_length)) {
David Benjamin8f820b42016-11-30 11:24:40 -0500348 return ssl_hs_error;
349 }
Steven Valdez908ac192017-01-12 13:17:07 -0500350 } else if (!tls13_advance_key_schedule(hs, kZeroes, hs->hash_len)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400351 return ssl_hs_error;
352 }
353
David Benjaminf01f42a2016-11-16 19:05:33 +0900354 ssl->method->received_flight(ssl);
355
Steven Valdez143e8b32016-07-11 13:19:03 -0400356 /* Resolve ECDHE and incorporate it into the secret. */
Steven Valdez5440fe02016-07-18 12:40:30 -0400357 int need_retry;
David Benjamin6e4fc332016-11-17 16:43:08 +0900358 if (!resolve_ecdhe_secret(hs, &need_retry, &client_hello)) {
Steven Valdez5440fe02016-07-18 12:40:30 -0400359 if (need_retry) {
David Benjamin3977f302016-12-11 13:30:41 -0500360 hs->tls13_state = state_send_hello_retry_request;
Steven Valdez5440fe02016-07-18 12:40:30 -0400361 return ssl_hs_ok;
Steven Valdez143e8b32016-07-11 13:19:03 -0400362 }
Steven Valdez5440fe02016-07-18 12:40:30 -0400363 return ssl_hs_error;
364 }
Steven Valdez143e8b32016-07-11 13:19:03 -0400365
David Benjamin3977f302016-12-11 13:30:41 -0500366 hs->tls13_state = state_send_server_hello;
Steven Valdez5440fe02016-07-18 12:40:30 -0400367 return ssl_hs_ok;
368}
Steven Valdez143e8b32016-07-11 13:19:03 -0400369
David Benjaminc3c88822016-11-14 10:32:04 +0900370static enum ssl_hs_wait_t do_send_hello_retry_request(SSL_HANDSHAKE *hs) {
371 SSL *const ssl = hs->ssl;
Steven Valdez5440fe02016-07-18 12:40:30 -0400372 CBB cbb, body, extensions;
373 uint16_t group_id;
374 if (!ssl->method->init_message(ssl, &cbb, &body,
375 SSL3_MT_HELLO_RETRY_REQUEST) ||
376 !CBB_add_u16(&body, ssl->version) ||
David Benjaminf3c8f8d2016-11-17 17:20:47 +0900377 !tls1_get_shared_group(hs, &group_id) ||
Steven Valdez5440fe02016-07-18 12:40:30 -0400378 !CBB_add_u16_length_prefixed(&body, &extensions) ||
David Benjamin3baa6e12016-10-07 21:10:38 -0400379 !CBB_add_u16(&extensions, TLSEXT_TYPE_key_share) ||
380 !CBB_add_u16(&extensions, 2 /* length */) ||
381 !CBB_add_u16(&extensions, group_id) ||
David Benjamindaf207a2017-01-03 18:37:41 -0500382 !ssl_add_message_cbb(ssl, &cbb)) {
Steven Valdez5440fe02016-07-18 12:40:30 -0400383 CBB_cleanup(&cbb);
384 return ssl_hs_error;
385 }
386
David Benjamin3977f302016-12-11 13:30:41 -0500387 hs->tls13_state = state_process_second_client_hello;
Steven Valdez5440fe02016-07-18 12:40:30 -0400388 return ssl_hs_flush_and_read_message;
389}
390
David Benjaminc3c88822016-11-14 10:32:04 +0900391static enum ssl_hs_wait_t do_process_second_client_hello(SSL_HANDSHAKE *hs) {
392 SSL *const ssl = hs->ssl;
David Benjamin276b7e82017-01-21 14:13:39 -0500393 if (!ssl_check_message_type(ssl, SSL3_MT_CLIENT_HELLO)) {
Steven Valdez5440fe02016-07-18 12:40:30 -0400394 return ssl_hs_error;
395 }
396
David Benjamin731058e2016-12-03 23:15:13 -0500397 SSL_CLIENT_HELLO client_hello;
398 if (!ssl_client_hello_init(ssl, &client_hello, ssl->init_msg,
399 ssl->init_num)) {
Steven Valdez5440fe02016-07-18 12:40:30 -0400400 OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_PARSE_FAILED);
401 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
402 return ssl_hs_error;
403 }
404
405 int need_retry;
David Benjamin6e4fc332016-11-17 16:43:08 +0900406 if (!resolve_ecdhe_secret(hs, &need_retry, &client_hello)) {
Steven Valdez5440fe02016-07-18 12:40:30 -0400407 if (need_retry) {
408 /* Only send one HelloRetryRequest. */
409 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
410 OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CURVE);
Steven Valdez143e8b32016-07-11 13:19:03 -0400411 }
Steven Valdez5440fe02016-07-18 12:40:30 -0400412 return ssl_hs_error;
413 }
414
Steven Valdez908ac192017-01-12 13:17:07 -0500415 if (!ssl_hash_current_message(hs)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400416 return ssl_hs_error;
417 }
418
David Benjamin613fe3b2016-07-22 17:39:29 +0200419 ssl->method->received_flight(ssl);
David Benjamin3977f302016-12-11 13:30:41 -0500420 hs->tls13_state = state_send_server_hello;
Steven Valdez143e8b32016-07-11 13:19:03 -0400421 return ssl_hs_ok;
422}
423
David Benjaminc3c88822016-11-14 10:32:04 +0900424static enum ssl_hs_wait_t do_send_server_hello(SSL_HANDSHAKE *hs) {
425 SSL *const ssl = hs->ssl;
David Benjamin81b7bc32017-01-12 19:44:57 -0500426
427 /* Send a ServerHello. */
Steven Valdez143e8b32016-07-11 13:19:03 -0400428 CBB cbb, body, extensions;
429 if (!ssl->method->init_message(ssl, &cbb, &body, SSL3_MT_SERVER_HELLO) ||
430 !CBB_add_u16(&body, ssl->version) ||
431 !RAND_bytes(ssl->s3->server_random, sizeof(ssl->s3->server_random)) ||
432 !CBB_add_bytes(&body, ssl->s3->server_random, SSL3_RANDOM_SIZE) ||
David Benjamin45738dd2017-02-09 20:01:26 -0500433 !CBB_add_u16(&body, ssl_cipher_get_value(hs->new_cipher)) ||
Steven Valdez143e8b32016-07-11 13:19:03 -0400434 !CBB_add_u16_length_prefixed(&body, &extensions) ||
David Benjamin8baf9632016-11-17 17:11:16 +0900435 !ssl_ext_pre_shared_key_add_serverhello(hs, &extensions) ||
Steven Valdez924a3522017-03-02 16:05:03 -0500436 !ssl_ext_key_share_add_serverhello(hs, &extensions) ||
437 !ssl_add_message_cbb(ssl, &cbb)) {
Steven Valdez803c77a2016-09-06 14:13:43 -0400438 goto err;
Steven Valdez143e8b32016-07-11 13:19:03 -0400439 }
440
David Benjamin81b7bc32017-01-12 19:44:57 -0500441 /* Derive and enable the handshake traffic secrets. */
Steven Valdez4cb84942016-12-16 11:29:28 -0500442 if (!tls13_derive_handshake_secrets(hs) ||
443 !tls13_set_traffic_key(ssl, evp_aead_open, hs->client_handshake_secret,
444 hs->hash_len) ||
445 !tls13_set_traffic_key(ssl, evp_aead_seal, hs->server_handshake_secret,
446 hs->hash_len)) {
David Benjamin81b7bc32017-01-12 19:44:57 -0500447 goto err;
Steven Valdez143e8b32016-07-11 13:19:03 -0400448 }
449
David Benjamin81b7bc32017-01-12 19:44:57 -0500450 /* Send EncryptedExtensions. */
Steven Valdez143e8b32016-07-11 13:19:03 -0400451 if (!ssl->method->init_message(ssl, &cbb, &body,
452 SSL3_MT_ENCRYPTED_EXTENSIONS) ||
David Benjamin8c880a22016-12-03 02:20:34 -0500453 !ssl_add_serverhello_tlsext(hs, &body) ||
David Benjamindaf207a2017-01-03 18:37:41 -0500454 !ssl_add_message_cbb(ssl, &cbb)) {
David Benjamin81b7bc32017-01-12 19:44:57 -0500455 goto err;
Steven Valdez143e8b32016-07-11 13:19:03 -0400456 }
457
Steven Valdez143e8b32016-07-11 13:19:03 -0400458 /* Determine whether to request a client certificate. */
David Benjaminc3c88822016-11-14 10:32:04 +0900459 hs->cert_request = !!(ssl->verify_mode & SSL_VERIFY_PEER);
Steven Valdez803c77a2016-09-06 14:13:43 -0400460 /* CertificateRequest may only be sent in non-resumption handshakes. */
461 if (ssl->s3->session_reused) {
David Benjaminc3c88822016-11-14 10:32:04 +0900462 hs->cert_request = 0;
Steven Valdez143e8b32016-07-11 13:19:03 -0400463 }
464
David Benjamin81b7bc32017-01-12 19:44:57 -0500465 /* Send a CertificateRequest, if necessary. */
466 if (hs->cert_request) {
467 CBB sigalgs_cbb;
468 if (!ssl->method->init_message(ssl, &cbb, &body,
469 SSL3_MT_CERTIFICATE_REQUEST) ||
470 !CBB_add_u8(&body, 0 /* no certificate_request_context. */)) {
471 goto err;
472 }
Steven Valdez143e8b32016-07-11 13:19:03 -0400473
David Benjamin81b7bc32017-01-12 19:44:57 -0500474 const uint16_t *sigalgs;
475 size_t num_sigalgs = tls12_get_verify_sigalgs(ssl, &sigalgs);
476 if (!CBB_add_u16_length_prefixed(&body, &sigalgs_cbb)) {
477 goto err;
478 }
Steven Valdez143e8b32016-07-11 13:19:03 -0400479
David Benjamin81b7bc32017-01-12 19:44:57 -0500480 for (size_t i = 0; i < num_sigalgs; i++) {
481 if (!CBB_add_u16(&sigalgs_cbb, sigalgs[i])) {
482 goto err;
483 }
484 }
Steven Valdez143e8b32016-07-11 13:19:03 -0400485
David Benjamin81b7bc32017-01-12 19:44:57 -0500486 if (!ssl_add_client_CA_list(ssl, &body) ||
487 !CBB_add_u16(&body, 0 /* empty certificate_extensions. */) ||
488 !ssl_add_message_cbb(ssl, &cbb)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400489 goto err;
490 }
491 }
492
David Benjamin81b7bc32017-01-12 19:44:57 -0500493 /* Send the server Certificate message, if necessary. */
494 if (!ssl->s3->session_reused) {
495 if (!ssl_has_certificate(ssl)) {
496 OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATE_SET);
497 goto err;
498 }
499
David Benjamin0f24bed2017-01-12 19:46:50 -0500500 if (!tls13_add_certificate(hs)) {
David Benjamin81b7bc32017-01-12 19:44:57 -0500501 goto err;
502 }
503
504 hs->tls13_state = state_send_server_certificate_verify;
505 return ssl_hs_ok;
Steven Valdez143e8b32016-07-11 13:19:03 -0400506 }
507
David Benjamin81b7bc32017-01-12 19:44:57 -0500508 hs->tls13_state = state_send_server_finished;
David Benjamin25ac2512017-01-12 19:31:28 -0500509 return ssl_hs_ok;
Steven Valdez143e8b32016-07-11 13:19:03 -0400510
511err:
512 CBB_cleanup(&cbb);
513 return ssl_hs_error;
514}
515
David Benjaminc3c88822016-11-14 10:32:04 +0900516static enum ssl_hs_wait_t do_send_server_certificate_verify(SSL_HANDSHAKE *hs,
Steven Valdez143e8b32016-07-11 13:19:03 -0400517 int is_first_run) {
David Benjamin0f24bed2017-01-12 19:46:50 -0500518 switch (tls13_add_certificate_verify(hs, is_first_run)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400519 case ssl_private_key_success:
David Benjamin3977f302016-12-11 13:30:41 -0500520 hs->tls13_state = state_send_server_finished;
David Benjamin25ac2512017-01-12 19:31:28 -0500521 return ssl_hs_ok;
Steven Valdez143e8b32016-07-11 13:19:03 -0400522
523 case ssl_private_key_retry:
David Benjamin3977f302016-12-11 13:30:41 -0500524 hs->tls13_state = state_complete_server_certificate_verify;
Steven Valdez143e8b32016-07-11 13:19:03 -0400525 return ssl_hs_private_key_operation;
526
527 case ssl_private_key_failure:
528 return ssl_hs_error;
529 }
530
531 assert(0);
532 return ssl_hs_error;
533}
534
David Benjaminc3c88822016-11-14 10:32:04 +0900535static enum ssl_hs_wait_t do_send_server_finished(SSL_HANDSHAKE *hs) {
David Benjaminc3c88822016-11-14 10:32:04 +0900536 SSL *const ssl = hs->ssl;
David Benjamin0f24bed2017-01-12 19:46:50 -0500537 if (!tls13_add_finished(hs) ||
David Benjamin25ac2512017-01-12 19:31:28 -0500538 /* Update the secret to the master secret and derive traffic keys. */
539 !tls13_advance_key_schedule(hs, kZeroes, hs->hash_len) ||
David Benjamin6e4fc332016-11-17 16:43:08 +0900540 !tls13_derive_application_secrets(hs) ||
Steven Valdeza833c352016-11-01 13:39:36 -0400541 !tls13_set_traffic_key(ssl, evp_aead_seal, hs->server_traffic_secret_0,
542 hs->hash_len)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400543 return ssl_hs_error;
544 }
545
David Benjamin3977f302016-12-11 13:30:41 -0500546 hs->tls13_state = state_process_client_certificate;
David Benjaminf2401eb2016-07-18 22:25:05 +0200547 return ssl_hs_flush_and_read_message;
Steven Valdez143e8b32016-07-11 13:19:03 -0400548}
549
David Benjaminc3c88822016-11-14 10:32:04 +0900550static enum ssl_hs_wait_t do_process_client_certificate(SSL_HANDSHAKE *hs) {
551 SSL *const ssl = hs->ssl;
552 if (!hs->cert_request) {
Adam Langley37646832016-08-01 16:16:46 -0700553 /* OpenSSL returns X509_V_OK when no certificates are requested. This is
David Benjamindd634eb2016-08-18 16:40:28 -0400554 * classed by them as a bug, but it's assumed by at least NGINX. */
David Benjamin45738dd2017-02-09 20:01:26 -0500555 hs->new_session->verify_result = X509_V_OK;
Adam Langley37646832016-08-01 16:16:46 -0700556
Steven Valdez143e8b32016-07-11 13:19:03 -0400557 /* Skip this state. */
David Benjamin3977f302016-12-11 13:30:41 -0500558 hs->tls13_state = state_process_channel_id;
Steven Valdez143e8b32016-07-11 13:19:03 -0400559 return ssl_hs_ok;
560 }
561
David Benjamin4087df92016-08-01 20:16:31 -0400562 const int allow_anonymous =
563 (ssl->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) == 0;
564
David Benjamin276b7e82017-01-21 14:13:39 -0500565 if (!ssl_check_message_type(ssl, SSL3_MT_CERTIFICATE) ||
Adam Langley0c294252016-12-12 11:46:09 -0800566 !tls13_process_certificate(hs, allow_anonymous) ||
Steven Valdez908ac192017-01-12 13:17:07 -0500567 !ssl_hash_current_message(hs)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400568 return ssl_hs_error;
569 }
570
David Benjamin3977f302016-12-11 13:30:41 -0500571 hs->tls13_state = state_process_client_certificate_verify;
Steven Valdez143e8b32016-07-11 13:19:03 -0400572 return ssl_hs_read_message;
573}
574
575static enum ssl_hs_wait_t do_process_client_certificate_verify(
David Benjaminc3c88822016-11-14 10:32:04 +0900576 SSL_HANDSHAKE *hs) {
577 SSL *const ssl = hs->ssl;
David Benjamin45738dd2017-02-09 20:01:26 -0500578 if (sk_CRYPTO_BUFFER_num(hs->new_session->certs) == 0) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400579 /* Skip this state. */
David Benjamin3977f302016-12-11 13:30:41 -0500580 hs->tls13_state = state_process_channel_id;
Steven Valdez143e8b32016-07-11 13:19:03 -0400581 return ssl_hs_ok;
582 }
583
David Benjamin276b7e82017-01-21 14:13:39 -0500584 if (!ssl_check_message_type(ssl, SSL3_MT_CERTIFICATE_VERIFY) ||
Adam Langley0c294252016-12-12 11:46:09 -0800585 !tls13_process_certificate_verify(hs) ||
Steven Valdez908ac192017-01-12 13:17:07 -0500586 !ssl_hash_current_message(hs)) {
David Benjamin6929f272016-11-16 19:10:08 +0900587 return ssl_hs_error;
Steven Valdez143e8b32016-07-11 13:19:03 -0400588 }
589
David Benjamin3977f302016-12-11 13:30:41 -0500590 hs->tls13_state = state_process_channel_id;
Nick Harper60a85cb2016-09-23 16:25:11 -0700591 return ssl_hs_read_message;
592}
593
David Benjaminc3c88822016-11-14 10:32:04 +0900594static enum ssl_hs_wait_t do_process_channel_id(SSL_HANDSHAKE *hs) {
Steven Valdez908ac192017-01-12 13:17:07 -0500595 if (!hs->ssl->s3->tlsext_channel_id_valid) {
David Benjamin3977f302016-12-11 13:30:41 -0500596 hs->tls13_state = state_process_client_finished;
Nick Harper60a85cb2016-09-23 16:25:11 -0700597 return ssl_hs_ok;
598 }
599
Steven Valdez908ac192017-01-12 13:17:07 -0500600 if (!ssl_check_message_type(hs->ssl, SSL3_MT_CHANNEL_ID) ||
601 !tls1_verify_channel_id(hs) ||
602 !ssl_hash_current_message(hs)) {
Nick Harper60a85cb2016-09-23 16:25:11 -0700603 return ssl_hs_error;
604 }
605
David Benjamin3977f302016-12-11 13:30:41 -0500606 hs->tls13_state = state_process_client_finished;
Steven Valdez143e8b32016-07-11 13:19:03 -0400607 return ssl_hs_read_message;
608}
609
David Benjaminc3c88822016-11-14 10:32:04 +0900610static enum ssl_hs_wait_t do_process_client_finished(SSL_HANDSHAKE *hs) {
611 SSL *const ssl = hs->ssl;
David Benjamin276b7e82017-01-21 14:13:39 -0500612 if (!ssl_check_message_type(ssl, SSL3_MT_FINISHED) ||
David Benjamin6e4fc332016-11-17 16:43:08 +0900613 !tls13_process_finished(hs) ||
Steven Valdez908ac192017-01-12 13:17:07 -0500614 !ssl_hash_current_message(hs) ||
Steven Valdez143e8b32016-07-11 13:19:03 -0400615 /* evp_aead_seal keys have already been switched. */
Steven Valdeza833c352016-11-01 13:39:36 -0400616 !tls13_set_traffic_key(ssl, evp_aead_open, hs->client_traffic_secret_0,
617 hs->hash_len) ||
David Benjamin6e4fc332016-11-17 16:43:08 +0900618 !tls13_derive_resumption_secret(hs)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400619 return ssl_hs_error;
620 }
621
David Benjamin613fe3b2016-07-22 17:39:29 +0200622 ssl->method->received_flight(ssl);
David Benjamin123db572016-11-03 16:59:25 -0400623
David Benjamin17b30832017-01-28 14:00:32 -0500624 /* Rebase the session timestamp so that it is measured from ticket
David Benjamin123db572016-11-03 16:59:25 -0400625 * issuance. */
David Benjamin45738dd2017-02-09 20:01:26 -0500626 ssl_session_rebase_time(ssl, hs->new_session);
David Benjamin3977f302016-12-11 13:30:41 -0500627 hs->tls13_state = state_send_new_session_ticket;
Steven Valdez143e8b32016-07-11 13:19:03 -0400628 return ssl_hs_ok;
629}
630
David Benjaminc3c88822016-11-14 10:32:04 +0900631static enum ssl_hs_wait_t do_send_new_session_ticket(SSL_HANDSHAKE *hs) {
David Benjamin25ac2512017-01-12 19:31:28 -0500632 /* TLS 1.3 recommends single-use tickets, so issue multiple tickets in case the
633 * client makes several connections before getting a renewal. */
634 static const int kNumTickets = 2;
635
David Benjaminc3c88822016-11-14 10:32:04 +0900636 SSL *const ssl = hs->ssl;
Steven Valdeza833c352016-11-01 13:39:36 -0400637 /* If the client doesn't accept resumption with PSK_DHE_KE, don't send a
638 * session ticket. */
639 if (!hs->accept_psk_mode) {
David Benjamin3977f302016-12-11 13:30:41 -0500640 hs->tls13_state = state_done;
Steven Valdeza833c352016-11-01 13:39:36 -0400641 return ssl_hs_ok;
642 }
643
David Benjamin45738dd2017-02-09 20:01:26 -0500644 SSL_SESSION *session = hs->new_session;
David Benjamin25ac2512017-01-12 19:31:28 -0500645 CBB cbb;
646 CBB_zero(&cbb);
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400647
David Benjamin25ac2512017-01-12 19:31:28 -0500648 for (int i = 0; i < kNumTickets; i++) {
649 if (!RAND_bytes((uint8_t *)&session->ticket_age_add, 4)) {
650 goto err;
651 }
David Benjamin35ac5b72017-03-03 15:05:56 -0500652 session->ticket_age_add_valid = 1;
David Benjamin1a5e8ec2016-10-07 15:19:18 -0400653
David Benjamin25ac2512017-01-12 19:31:28 -0500654 CBB body, ticket, extensions;
655 if (!ssl->method->init_message(ssl, &cbb, &body,
656 SSL3_MT_NEW_SESSION_TICKET) ||
657 !CBB_add_u32(&body, session->timeout) ||
658 !CBB_add_u32(&body, session->ticket_age_add) ||
659 !CBB_add_u16_length_prefixed(&body, &ticket) ||
660 !ssl_encrypt_ticket(ssl, &ticket, session) ||
661 !CBB_add_u16_length_prefixed(&body, &extensions)) {
662 goto err;
663 }
Steven Valdez08b65f42016-12-07 15:29:45 -0500664
David Benjamin25ac2512017-01-12 19:31:28 -0500665 if (ssl->ctx->enable_early_data) {
666 session->ticket_max_early_data = kMaxEarlyDataAccepted;
667
668 CBB early_data_info;
669 if (!CBB_add_u16(&extensions, TLSEXT_TYPE_ticket_early_data_info) ||
670 !CBB_add_u16_length_prefixed(&extensions, &early_data_info) ||
671 !CBB_add_u32(&early_data_info, session->ticket_max_early_data) ||
672 !CBB_flush(&extensions)) {
673 goto err;
674 }
675 }
676
677 /* Add a fake extension. See draft-davidben-tls-grease-01. */
678 if (!CBB_add_u16(&extensions,
679 ssl_get_grease_value(ssl, ssl_grease_ticket_extension)) ||
680 !CBB_add_u16(&extensions, 0 /* empty */)) {
681 goto err;
682 }
683
684 if (!ssl_add_message_cbb(ssl, &cbb)) {
Steven Valdez08b65f42016-12-07 15:29:45 -0500685 goto err;
686 }
687 }
688
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400689 hs->session_tickets_sent++;
David Benjamin25ac2512017-01-12 19:31:28 -0500690 hs->tls13_state = state_done;
691 return ssl_hs_flush;
David Benjamin1a5e8ec2016-10-07 15:19:18 -0400692
693err:
694 CBB_cleanup(&cbb);
695 return ssl_hs_error;
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400696}
697
David Benjaminc3c88822016-11-14 10:32:04 +0900698enum ssl_hs_wait_t tls13_server_handshake(SSL_HANDSHAKE *hs) {
David Benjamin3977f302016-12-11 13:30:41 -0500699 while (hs->tls13_state != state_done) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400700 enum ssl_hs_wait_t ret = ssl_hs_error;
David Benjamin3977f302016-12-11 13:30:41 -0500701 enum server_hs_state_t state = hs->tls13_state;
Steven Valdez143e8b32016-07-11 13:19:03 -0400702 switch (state) {
David Benjamin25fe85b2016-08-09 20:00:32 -0400703 case state_select_parameters:
David Benjaminc3c88822016-11-14 10:32:04 +0900704 ret = do_select_parameters(hs);
David Benjamin25fe85b2016-08-09 20:00:32 -0400705 break;
David Benjamin707af292017-03-10 17:47:18 -0500706 case state_select_session:
707 ret = do_select_session(hs);
708 break;
Steven Valdez5440fe02016-07-18 12:40:30 -0400709 case state_send_hello_retry_request:
David Benjaminc3c88822016-11-14 10:32:04 +0900710 ret = do_send_hello_retry_request(hs);
Steven Valdez5440fe02016-07-18 12:40:30 -0400711 break;
Steven Valdez5440fe02016-07-18 12:40:30 -0400712 case state_process_second_client_hello:
David Benjaminc3c88822016-11-14 10:32:04 +0900713 ret = do_process_second_client_hello(hs);
Steven Valdez5440fe02016-07-18 12:40:30 -0400714 break;
Steven Valdez143e8b32016-07-11 13:19:03 -0400715 case state_send_server_hello:
David Benjaminc3c88822016-11-14 10:32:04 +0900716 ret = do_send_server_hello(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400717 break;
Steven Valdez143e8b32016-07-11 13:19:03 -0400718 case state_send_server_certificate_verify:
David Benjaminc3c88822016-11-14 10:32:04 +0900719 ret = do_send_server_certificate_verify(hs, 1 /* first run */);
Steven Valdez143e8b32016-07-11 13:19:03 -0400720 break;
721 case state_complete_server_certificate_verify:
David Benjaminc3c88822016-11-14 10:32:04 +0900722 ret = do_send_server_certificate_verify(hs, 0 /* complete */);
Steven Valdez143e8b32016-07-11 13:19:03 -0400723 break;
724 case state_send_server_finished:
David Benjaminc3c88822016-11-14 10:32:04 +0900725 ret = do_send_server_finished(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400726 break;
Steven Valdez143e8b32016-07-11 13:19:03 -0400727 case state_process_client_certificate:
David Benjaminc3c88822016-11-14 10:32:04 +0900728 ret = do_process_client_certificate(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400729 break;
730 case state_process_client_certificate_verify:
David Benjaminc3c88822016-11-14 10:32:04 +0900731 ret = do_process_client_certificate_verify(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400732 break;
Nick Harper60a85cb2016-09-23 16:25:11 -0700733 case state_process_channel_id:
David Benjaminc3c88822016-11-14 10:32:04 +0900734 ret = do_process_channel_id(hs);
Nick Harper60a85cb2016-09-23 16:25:11 -0700735 break;
Steven Valdez143e8b32016-07-11 13:19:03 -0400736 case state_process_client_finished:
David Benjaminc3c88822016-11-14 10:32:04 +0900737 ret = do_process_client_finished(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400738 break;
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400739 case state_send_new_session_ticket:
David Benjaminc3c88822016-11-14 10:32:04 +0900740 ret = do_send_new_session_ticket(hs);
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400741 break;
Steven Valdez143e8b32016-07-11 13:19:03 -0400742 case state_done:
743 ret = ssl_hs_ok;
744 break;
745 }
746
747 if (ret != ssl_hs_ok) {
748 return ret;
749 }
750 }
751
752 return ssl_hs_ok;
753}