blob: 4136a69378fd57add4a55bc9b8d80bdc684fd18e [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,
Steven Valdez5440fe02016-07-18 12:40:30 -040039 state_send_hello_retry_request,
Steven Valdez5440fe02016-07-18 12:40:30 -040040 state_process_second_client_hello,
Steven Valdez143e8b32016-07-11 13:19:03 -040041 state_send_server_hello,
Steven Valdez143e8b32016-07-11 13:19:03 -040042 state_send_server_certificate_verify,
43 state_complete_server_certificate_verify,
44 state_send_server_finished,
Steven Valdez143e8b32016-07-11 13:19:03 -040045 state_process_client_certificate,
46 state_process_client_certificate_verify,
Nick Harper60a85cb2016-09-23 16:25:11 -070047 state_process_channel_id,
Steven Valdez143e8b32016-07-11 13:19:03 -040048 state_process_client_finished,
Steven Valdez1e6f11a2016-07-27 11:10:52 -040049 state_send_new_session_ticket,
Steven Valdez143e8b32016-07-11 13:19:03 -040050 state_done,
51};
52
Steven Valdez5440fe02016-07-18 12:40:30 -040053static const uint8_t kZeroes[EVP_MAX_MD_SIZE] = {0};
54
David Benjamin6e4fc332016-11-17 16:43:08 +090055static int resolve_ecdhe_secret(SSL_HANDSHAKE *hs, int *out_need_retry,
David Benjamin731058e2016-12-03 23:15:13 -050056 SSL_CLIENT_HELLO *client_hello) {
David Benjamin6e4fc332016-11-17 16:43:08 +090057 SSL *const ssl = hs->ssl;
Steven Valdez5440fe02016-07-18 12:40:30 -040058 *out_need_retry = 0;
Steven Valdez5440fe02016-07-18 12:40:30 -040059
Steven Valdez803c77a2016-09-06 14:13:43 -040060 /* We only support connections that include an ECDHE key exchange. */
Steven Valdez5440fe02016-07-18 12:40:30 -040061 CBS key_share;
David Benjamin731058e2016-12-03 23:15:13 -050062 if (!ssl_client_hello_get_extension(client_hello, &key_share,
63 TLSEXT_TYPE_key_share)) {
Steven Valdez5440fe02016-07-18 12:40:30 -040064 OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_KEY_SHARE);
65 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_MISSING_EXTENSION);
David Benjamin6929f272016-11-16 19:10:08 +090066 return 0;
Steven Valdez5440fe02016-07-18 12:40:30 -040067 }
68
Steven Valdez5440fe02016-07-18 12:40:30 -040069 int found_key_share;
70 uint8_t *dhe_secret;
71 size_t dhe_secret_len;
David Benjamin7e1f9842016-09-20 19:24:40 -040072 uint8_t alert = SSL_AD_DECODE_ERROR;
David Benjamin8baf9632016-11-17 17:11:16 +090073 if (!ssl_ext_key_share_parse_clienthello(hs, &found_key_share, &dhe_secret,
Steven Valdez7259f2f2016-08-02 16:55:05 -040074 &dhe_secret_len, &alert,
75 &key_share)) {
Steven Valdez5440fe02016-07-18 12:40:30 -040076 ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
77 return 0;
78 }
79
80 if (!found_key_share) {
81 *out_need_retry = 1;
82 return 0;
83 }
84
David Benjamin6e4fc332016-11-17 16:43:08 +090085 int ok = tls13_advance_key_schedule(hs, dhe_secret, dhe_secret_len);
Steven Valdez5440fe02016-07-18 12:40:30 -040086 OPENSSL_free(dhe_secret);
87 return ok;
88}
89
David Benjamin34202b92016-11-16 19:07:53 +090090static const SSL_CIPHER *choose_tls13_cipher(
David Benjamin731058e2016-12-03 23:15:13 -050091 const SSL *ssl, const SSL_CLIENT_HELLO *client_hello) {
David Benjamin34202b92016-11-16 19:07:53 +090092 if (client_hello->cipher_suites_len % 2 != 0) {
93 return NULL;
94 }
95
96 CBS cipher_suites;
97 CBS_init(&cipher_suites, client_hello->cipher_suites,
98 client_hello->cipher_suites_len);
99
100 const int aes_is_fine = EVP_has_aes_hardware();
David Benjaminf01f42a2016-11-16 19:05:33 +0900101 const uint16_t version = ssl3_protocol_version(ssl);
David Benjamin34202b92016-11-16 19:07:53 +0900102
103 const SSL_CIPHER *best = NULL;
104 while (CBS_len(&cipher_suites) > 0) {
105 uint16_t cipher_suite;
106 if (!CBS_get_u16(&cipher_suites, &cipher_suite)) {
107 return NULL;
108 }
109
David Benjaminf01f42a2016-11-16 19:05:33 +0900110 /* Limit to TLS 1.3 ciphers we know about. */
David Benjamin34202b92016-11-16 19:07:53 +0900111 const SSL_CIPHER *candidate = SSL_get_cipher_by_value(cipher_suite);
David Benjaminf01f42a2016-11-16 19:05:33 +0900112 if (candidate == NULL ||
113 SSL_CIPHER_get_min_version(candidate) > version ||
114 SSL_CIPHER_get_max_version(candidate) < version) {
David Benjamin34202b92016-11-16 19:07:53 +0900115 continue;
116 }
117
118 /* TLS 1.3 removes legacy ciphers, so honor the client order, but prefer
119 * ChaCha20 if we do not have AES hardware. */
120 if (aes_is_fine) {
121 return candidate;
122 }
123
124 if (candidate->algorithm_enc == SSL_CHACHA20POLY1305) {
125 return candidate;
126 }
127
128 if (best == NULL) {
129 best = candidate;
130 }
131 }
132
133 return best;
134}
135
David Benjaminc3c88822016-11-14 10:32:04 +0900136static enum ssl_hs_wait_t do_select_parameters(SSL_HANDSHAKE *hs) {
137 SSL *const ssl = hs->ssl;
David Benjamin650aa1c2016-12-20 18:55:16 -0500138
David Benjamin731058e2016-12-03 23:15:13 -0500139 SSL_CLIENT_HELLO client_hello;
140 if (!ssl_client_hello_init(ssl, &client_hello, ssl->init_msg,
141 ssl->init_num)) {
David Benjamin34202b92016-11-16 19:07:53 +0900142 OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_PARSE_FAILED);
143 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
144 return ssl_hs_error;
145 }
146
David Benjaminf01f42a2016-11-16 19:05:33 +0900147 /* Negotiate the cipher suite. */
David Benjamin45738dd2017-02-09 20:01:26 -0500148 hs->new_cipher = choose_tls13_cipher(ssl, &client_hello);
149 if (hs->new_cipher == NULL) {
David Benjaminf01f42a2016-11-16 19:05:33 +0900150 OPENSSL_PUT_ERROR(SSL, SSL_R_NO_SHARED_CIPHER);
151 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
152 return ssl_hs_error;
153 }
154
Steven Valdez908ac192017-01-12 13:17:07 -0500155 /* The PRF hash is now known. Set up the key schedule and hash the
156 * ClientHello. */
157 if (!tls13_init_key_schedule(hs) ||
158 !ssl_hash_current_message(hs)) {
159 return ssl_hs_error;
160 }
161
162
David Benjaminf01f42a2016-11-16 19:05:33 +0900163 /* Decode the ticket if we agree on a PSK key exchange mode. */
David Benjamin4eb95cc2016-11-16 17:08:23 +0900164 uint8_t alert = SSL_AD_DECODE_ERROR;
165 SSL_SESSION *session = NULL;
David Benjamin35ac5b72017-03-03 15:05:56 -0500166 uint32_t client_ticket_age = 0;
David Benjamin4eb95cc2016-11-16 17:08:23 +0900167 CBS pre_shared_key, binders;
168 if (hs->accept_psk_mode &&
David Benjamin731058e2016-12-03 23:15:13 -0500169 ssl_client_hello_get_extension(&client_hello, &pre_shared_key,
170 TLSEXT_TYPE_pre_shared_key)) {
David Benjamin4eb95cc2016-11-16 17:08:23 +0900171 /* Verify that the pre_shared_key extension is the last extension in
172 * ClientHello. */
173 if (CBS_data(&pre_shared_key) + CBS_len(&pre_shared_key) !=
174 client_hello.extensions + client_hello.extensions_len) {
175 OPENSSL_PUT_ERROR(SSL, SSL_R_PRE_SHARED_KEY_MUST_BE_LAST);
176 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
177 return ssl_hs_error;
178 }
179
David Benjamin8baf9632016-11-17 17:11:16 +0900180 if (!ssl_ext_pre_shared_key_parse_clienthello(hs, &session, &binders,
David Benjamin35ac5b72017-03-03 15:05:56 -0500181 &client_ticket_age, &alert,
182 &pre_shared_key)) {
David Benjamin4eb95cc2016-11-16 17:08:23 +0900183 ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
184 return ssl_hs_error;
Steven Valdeza833c352016-11-01 13:39:36 -0400185 }
186 }
187
Steven Valdez4aa154e2016-07-29 14:32:55 -0400188 if (session != NULL &&
David Benjamin35ac5b72017-03-03 15:05:56 -0500189 (!ssl_session_is_resumable(hs, session) ||
190 /* Historically, some TLS 1.3 tickets were missing ticket_age_add. */
191 !session->ticket_age_add_valid)) {
Steven Valdez4aa154e2016-07-29 14:32:55 -0400192 SSL_SESSION_free(session);
193 session = NULL;
194 }
195
David Benjamin35ac5b72017-03-03 15:05:56 -0500196 if (session != NULL) {
197 /* Recover the client ticket age and convert to seconds. */
198 client_ticket_age -= session->ticket_age_add;
199 client_ticket_age /= 1000;
200
201 struct OPENSSL_timeval now;
202 ssl_get_current_time(ssl, &now);
203
204 /* Compute the server ticket age in seconds. */
205 assert(now.tv_sec >= session->time);
206 uint64_t server_ticket_age = now.tv_sec - session->time;
207
208 /* To avoid overflowing |hs->ticket_age_skew|, we will not resume
209 * 68-year-old sessions. */
210 if (server_ticket_age > INT32_MAX) {
211 SSL_SESSION_free(session);
212 session = NULL;
213 } else {
214 /* TODO(davidben,svaldez): Measure this value to decide on tolerance. For
215 * now, accept all values. https://crbug.com/boringssl/113. */
216 ssl->s3->ticket_age_skew =
217 (int32_t)client_ticket_age - (int32_t)server_ticket_age;
218 }
219 }
220
David Benjaminf01f42a2016-11-16 19:05:33 +0900221 /* Set up the new session, either using the original one as a template or
222 * creating a fresh one. */
Steven Valdez4aa154e2016-07-29 14:32:55 -0400223 if (session == NULL) {
David Benjaminf3c8f8d2016-11-17 17:20:47 +0900224 if (!ssl_get_new_session(hs, 1 /* server */)) {
Steven Valdez4aa154e2016-07-29 14:32:55 -0400225 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
226 return ssl_hs_error;
227 }
David Benjaminf01f42a2016-11-16 19:05:33 +0900228
David Benjamin45738dd2017-02-09 20:01:26 -0500229 hs->new_session->cipher = hs->new_cipher;
David Benjaminf01f42a2016-11-16 19:05:33 +0900230
231 /* On new sessions, stash the SNI value in the session. */
David Benjamin6e4fc332016-11-17 16:43:08 +0900232 if (hs->hostname != NULL) {
David Benjamin45738dd2017-02-09 20:01:26 -0500233 OPENSSL_free(hs->new_session->tlsext_hostname);
234 hs->new_session->tlsext_hostname = BUF_strdup(hs->hostname);
235 if (hs->new_session->tlsext_hostname == NULL) {
David Benjaminf01f42a2016-11-16 19:05:33 +0900236 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
237 return ssl_hs_error;
238 }
239 }
Steven Valdez4aa154e2016-07-29 14:32:55 -0400240 } else {
Steven Valdeza833c352016-11-01 13:39:36 -0400241 /* Check the PSK binder. */
Steven Valdez908ac192017-01-12 13:17:07 -0500242 if (!tls13_verify_psk_binder(hs, session, &binders)) {
Steven Valdeza833c352016-11-01 13:39:36 -0400243 SSL_SESSION_free(session);
244 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR);
245 return ssl_hs_error;
246 }
247
Steven Valdez4aa154e2016-07-29 14:32:55 -0400248 /* Only authentication information carries over in TLS 1.3. */
David Benjamin45738dd2017-02-09 20:01:26 -0500249 hs->new_session = SSL_SESSION_dup(session, SSL_SESSION_DUP_AUTH_ONLY);
250 if (hs->new_session == NULL) {
Steven Valdez4aa154e2016-07-29 14:32:55 -0400251 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
252 return ssl_hs_error;
253 }
254 ssl->s3->session_reused = 1;
Steven Valdez4aa154e2016-07-29 14:32:55 -0400255 SSL_SESSION_free(session);
David Benjamin17b30832017-01-28 14:00:32 -0500256
257 /* Resumption incorporates fresh key material, so refresh the timeout. */
David Benjamin45738dd2017-02-09 20:01:26 -0500258 ssl_session_renew_timeout(ssl, hs->new_session,
David Benjaminbe497062017-03-10 16:08:36 -0500259 ssl->session_ctx->session_psk_dhe_timeout);
Steven Valdez143e8b32016-07-11 13:19:03 -0400260 }
261
262 if (ssl->ctx->dos_protection_cb != NULL &&
David Benjamine14ff062016-08-09 16:21:24 -0400263 ssl->ctx->dos_protection_cb(&client_hello) == 0) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400264 /* Connection rejected for DOS reasons. */
265 OPENSSL_PUT_ERROR(SSL, SSL_R_CONNECTION_REJECTED);
David Benjamin2c66e072016-09-16 15:58:00 -0400266 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
Steven Valdez143e8b32016-07-11 13:19:03 -0400267 return ssl_hs_error;
268 }
269
David Benjaminf01f42a2016-11-16 19:05:33 +0900270 /* HTTP/2 negotiation depends on the cipher suite, so ALPN negotiation was
271 * deferred. Complete it now. */
Adam Langleyc68e5b92017-02-08 13:33:15 -0800272 alert = SSL_AD_DECODE_ERROR;
David Benjaminf3c8f8d2016-11-17 17:20:47 +0900273 if (!ssl_negotiate_alpn(hs, &alert, &client_hello)) {
David Benjamin9ef31f02016-10-31 18:01:13 -0400274 ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
275 return ssl_hs_error;
276 }
Steven Valdez803c77a2016-09-06 14:13:43 -0400277
Steven Valdez27a9e6a2017-02-14 13:20:40 -0500278 /* Store the initial negotiated ALPN in the session. */
279 if (ssl->s3->alpn_selected != NULL) {
David Benjamin45738dd2017-02-09 20:01:26 -0500280 hs->new_session->early_alpn =
Steven Valdez27a9e6a2017-02-14 13:20:40 -0500281 BUF_memdup(ssl->s3->alpn_selected, ssl->s3->alpn_selected_len);
David Benjamin45738dd2017-02-09 20:01:26 -0500282 if (hs->new_session->early_alpn == NULL) {
Steven Valdez27a9e6a2017-02-14 13:20:40 -0500283 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
284 return ssl_hs_error;
285 }
David Benjamin45738dd2017-02-09 20:01:26 -0500286 hs->new_session->early_alpn_len = ssl->s3->alpn_selected_len;
Steven Valdez27a9e6a2017-02-14 13:20:40 -0500287 }
288
David Benjamin8f820b42016-11-30 11:24:40 -0500289 /* Incorporate the PSK into the running secret. */
290 if (ssl->s3->session_reused) {
David Benjamin45738dd2017-02-09 20:01:26 -0500291 if (!tls13_advance_key_schedule(hs, hs->new_session->master_key,
292 hs->new_session->master_key_length)) {
David Benjamin8f820b42016-11-30 11:24:40 -0500293 return ssl_hs_error;
294 }
Steven Valdez908ac192017-01-12 13:17:07 -0500295 } else if (!tls13_advance_key_schedule(hs, kZeroes, hs->hash_len)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400296 return ssl_hs_error;
297 }
298
David Benjaminf01f42a2016-11-16 19:05:33 +0900299 ssl->method->received_flight(ssl);
300
Steven Valdez143e8b32016-07-11 13:19:03 -0400301 /* Resolve ECDHE and incorporate it into the secret. */
Steven Valdez5440fe02016-07-18 12:40:30 -0400302 int need_retry;
David Benjamin6e4fc332016-11-17 16:43:08 +0900303 if (!resolve_ecdhe_secret(hs, &need_retry, &client_hello)) {
Steven Valdez5440fe02016-07-18 12:40:30 -0400304 if (need_retry) {
David Benjamin3977f302016-12-11 13:30:41 -0500305 hs->tls13_state = state_send_hello_retry_request;
Steven Valdez5440fe02016-07-18 12:40:30 -0400306 return ssl_hs_ok;
Steven Valdez143e8b32016-07-11 13:19:03 -0400307 }
Steven Valdez5440fe02016-07-18 12:40:30 -0400308 return ssl_hs_error;
309 }
Steven Valdez143e8b32016-07-11 13:19:03 -0400310
David Benjamin3977f302016-12-11 13:30:41 -0500311 hs->tls13_state = state_send_server_hello;
Steven Valdez5440fe02016-07-18 12:40:30 -0400312 return ssl_hs_ok;
313}
Steven Valdez143e8b32016-07-11 13:19:03 -0400314
David Benjaminc3c88822016-11-14 10:32:04 +0900315static enum ssl_hs_wait_t do_send_hello_retry_request(SSL_HANDSHAKE *hs) {
316 SSL *const ssl = hs->ssl;
Steven Valdez5440fe02016-07-18 12:40:30 -0400317 CBB cbb, body, extensions;
318 uint16_t group_id;
319 if (!ssl->method->init_message(ssl, &cbb, &body,
320 SSL3_MT_HELLO_RETRY_REQUEST) ||
321 !CBB_add_u16(&body, ssl->version) ||
David Benjaminf3c8f8d2016-11-17 17:20:47 +0900322 !tls1_get_shared_group(hs, &group_id) ||
Steven Valdez5440fe02016-07-18 12:40:30 -0400323 !CBB_add_u16_length_prefixed(&body, &extensions) ||
David Benjamin3baa6e12016-10-07 21:10:38 -0400324 !CBB_add_u16(&extensions, TLSEXT_TYPE_key_share) ||
325 !CBB_add_u16(&extensions, 2 /* length */) ||
326 !CBB_add_u16(&extensions, group_id) ||
David Benjamindaf207a2017-01-03 18:37:41 -0500327 !ssl_add_message_cbb(ssl, &cbb)) {
Steven Valdez5440fe02016-07-18 12:40:30 -0400328 CBB_cleanup(&cbb);
329 return ssl_hs_error;
330 }
331
David Benjamin3977f302016-12-11 13:30:41 -0500332 hs->tls13_state = state_process_second_client_hello;
Steven Valdez5440fe02016-07-18 12:40:30 -0400333 return ssl_hs_flush_and_read_message;
334}
335
David Benjaminc3c88822016-11-14 10:32:04 +0900336static enum ssl_hs_wait_t do_process_second_client_hello(SSL_HANDSHAKE *hs) {
337 SSL *const ssl = hs->ssl;
David Benjamin276b7e82017-01-21 14:13:39 -0500338 if (!ssl_check_message_type(ssl, SSL3_MT_CLIENT_HELLO)) {
Steven Valdez5440fe02016-07-18 12:40:30 -0400339 return ssl_hs_error;
340 }
341
David Benjamin731058e2016-12-03 23:15:13 -0500342 SSL_CLIENT_HELLO client_hello;
343 if (!ssl_client_hello_init(ssl, &client_hello, ssl->init_msg,
344 ssl->init_num)) {
Steven Valdez5440fe02016-07-18 12:40:30 -0400345 OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_PARSE_FAILED);
346 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
347 return ssl_hs_error;
348 }
349
350 int need_retry;
David Benjamin6e4fc332016-11-17 16:43:08 +0900351 if (!resolve_ecdhe_secret(hs, &need_retry, &client_hello)) {
Steven Valdez5440fe02016-07-18 12:40:30 -0400352 if (need_retry) {
353 /* Only send one HelloRetryRequest. */
354 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
355 OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CURVE);
Steven Valdez143e8b32016-07-11 13:19:03 -0400356 }
Steven Valdez5440fe02016-07-18 12:40:30 -0400357 return ssl_hs_error;
358 }
359
Steven Valdez908ac192017-01-12 13:17:07 -0500360 if (!ssl_hash_current_message(hs)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400361 return ssl_hs_error;
362 }
363
David Benjamin613fe3b2016-07-22 17:39:29 +0200364 ssl->method->received_flight(ssl);
David Benjamin3977f302016-12-11 13:30:41 -0500365 hs->tls13_state = state_send_server_hello;
Steven Valdez143e8b32016-07-11 13:19:03 -0400366 return ssl_hs_ok;
367}
368
David Benjaminc3c88822016-11-14 10:32:04 +0900369static enum ssl_hs_wait_t do_send_server_hello(SSL_HANDSHAKE *hs) {
370 SSL *const ssl = hs->ssl;
David Benjamin81b7bc32017-01-12 19:44:57 -0500371
372 /* Send a ServerHello. */
Steven Valdez143e8b32016-07-11 13:19:03 -0400373 CBB cbb, body, extensions;
374 if (!ssl->method->init_message(ssl, &cbb, &body, SSL3_MT_SERVER_HELLO) ||
375 !CBB_add_u16(&body, ssl->version) ||
376 !RAND_bytes(ssl->s3->server_random, sizeof(ssl->s3->server_random)) ||
377 !CBB_add_bytes(&body, ssl->s3->server_random, SSL3_RANDOM_SIZE) ||
David Benjamin45738dd2017-02-09 20:01:26 -0500378 !CBB_add_u16(&body, ssl_cipher_get_value(hs->new_cipher)) ||
Steven Valdez143e8b32016-07-11 13:19:03 -0400379 !CBB_add_u16_length_prefixed(&body, &extensions) ||
David Benjamin8baf9632016-11-17 17:11:16 +0900380 !ssl_ext_pre_shared_key_add_serverhello(hs, &extensions) ||
Steven Valdez924a3522017-03-02 16:05:03 -0500381 !ssl_ext_key_share_add_serverhello(hs, &extensions) ||
382 !ssl_add_message_cbb(ssl, &cbb)) {
Steven Valdez803c77a2016-09-06 14:13:43 -0400383 goto err;
Steven Valdez143e8b32016-07-11 13:19:03 -0400384 }
385
David Benjamin81b7bc32017-01-12 19:44:57 -0500386 /* Derive and enable the handshake traffic secrets. */
Steven Valdez4cb84942016-12-16 11:29:28 -0500387 if (!tls13_derive_handshake_secrets(hs) ||
388 !tls13_set_traffic_key(ssl, evp_aead_open, hs->client_handshake_secret,
389 hs->hash_len) ||
390 !tls13_set_traffic_key(ssl, evp_aead_seal, hs->server_handshake_secret,
391 hs->hash_len)) {
David Benjamin81b7bc32017-01-12 19:44:57 -0500392 goto err;
Steven Valdez143e8b32016-07-11 13:19:03 -0400393 }
394
David Benjamin81b7bc32017-01-12 19:44:57 -0500395 /* Send EncryptedExtensions. */
Steven Valdez143e8b32016-07-11 13:19:03 -0400396 if (!ssl->method->init_message(ssl, &cbb, &body,
397 SSL3_MT_ENCRYPTED_EXTENSIONS) ||
David Benjamin8c880a22016-12-03 02:20:34 -0500398 !ssl_add_serverhello_tlsext(hs, &body) ||
David Benjamindaf207a2017-01-03 18:37:41 -0500399 !ssl_add_message_cbb(ssl, &cbb)) {
David Benjamin81b7bc32017-01-12 19:44:57 -0500400 goto err;
Steven Valdez143e8b32016-07-11 13:19:03 -0400401 }
402
Steven Valdez143e8b32016-07-11 13:19:03 -0400403 /* Determine whether to request a client certificate. */
David Benjaminc3c88822016-11-14 10:32:04 +0900404 hs->cert_request = !!(ssl->verify_mode & SSL_VERIFY_PEER);
Steven Valdez803c77a2016-09-06 14:13:43 -0400405 /* CertificateRequest may only be sent in non-resumption handshakes. */
406 if (ssl->s3->session_reused) {
David Benjaminc3c88822016-11-14 10:32:04 +0900407 hs->cert_request = 0;
Steven Valdez143e8b32016-07-11 13:19:03 -0400408 }
409
David Benjamin81b7bc32017-01-12 19:44:57 -0500410 /* Send a CertificateRequest, if necessary. */
411 if (hs->cert_request) {
412 CBB sigalgs_cbb;
413 if (!ssl->method->init_message(ssl, &cbb, &body,
414 SSL3_MT_CERTIFICATE_REQUEST) ||
415 !CBB_add_u8(&body, 0 /* no certificate_request_context. */)) {
416 goto err;
417 }
Steven Valdez143e8b32016-07-11 13:19:03 -0400418
David Benjamin81b7bc32017-01-12 19:44:57 -0500419 const uint16_t *sigalgs;
420 size_t num_sigalgs = tls12_get_verify_sigalgs(ssl, &sigalgs);
421 if (!CBB_add_u16_length_prefixed(&body, &sigalgs_cbb)) {
422 goto err;
423 }
Steven Valdez143e8b32016-07-11 13:19:03 -0400424
David Benjamin81b7bc32017-01-12 19:44:57 -0500425 for (size_t i = 0; i < num_sigalgs; i++) {
426 if (!CBB_add_u16(&sigalgs_cbb, sigalgs[i])) {
427 goto err;
428 }
429 }
Steven Valdez143e8b32016-07-11 13:19:03 -0400430
David Benjamin81b7bc32017-01-12 19:44:57 -0500431 if (!ssl_add_client_CA_list(ssl, &body) ||
432 !CBB_add_u16(&body, 0 /* empty certificate_extensions. */) ||
433 !ssl_add_message_cbb(ssl, &cbb)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400434 goto err;
435 }
436 }
437
David Benjamin81b7bc32017-01-12 19:44:57 -0500438 /* Send the server Certificate message, if necessary. */
439 if (!ssl->s3->session_reused) {
440 if (!ssl_has_certificate(ssl)) {
441 OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATE_SET);
442 goto err;
443 }
444
David Benjamin0f24bed2017-01-12 19:46:50 -0500445 if (!tls13_add_certificate(hs)) {
David Benjamin81b7bc32017-01-12 19:44:57 -0500446 goto err;
447 }
448
449 hs->tls13_state = state_send_server_certificate_verify;
450 return ssl_hs_ok;
Steven Valdez143e8b32016-07-11 13:19:03 -0400451 }
452
David Benjamin81b7bc32017-01-12 19:44:57 -0500453 hs->tls13_state = state_send_server_finished;
David Benjamin25ac2512017-01-12 19:31:28 -0500454 return ssl_hs_ok;
Steven Valdez143e8b32016-07-11 13:19:03 -0400455
456err:
457 CBB_cleanup(&cbb);
458 return ssl_hs_error;
459}
460
David Benjaminc3c88822016-11-14 10:32:04 +0900461static enum ssl_hs_wait_t do_send_server_certificate_verify(SSL_HANDSHAKE *hs,
Steven Valdez143e8b32016-07-11 13:19:03 -0400462 int is_first_run) {
David Benjamin0f24bed2017-01-12 19:46:50 -0500463 switch (tls13_add_certificate_verify(hs, is_first_run)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400464 case ssl_private_key_success:
David Benjamin3977f302016-12-11 13:30:41 -0500465 hs->tls13_state = state_send_server_finished;
David Benjamin25ac2512017-01-12 19:31:28 -0500466 return ssl_hs_ok;
Steven Valdez143e8b32016-07-11 13:19:03 -0400467
468 case ssl_private_key_retry:
David Benjamin3977f302016-12-11 13:30:41 -0500469 hs->tls13_state = state_complete_server_certificate_verify;
Steven Valdez143e8b32016-07-11 13:19:03 -0400470 return ssl_hs_private_key_operation;
471
472 case ssl_private_key_failure:
473 return ssl_hs_error;
474 }
475
476 assert(0);
477 return ssl_hs_error;
478}
479
David Benjaminc3c88822016-11-14 10:32:04 +0900480static enum ssl_hs_wait_t do_send_server_finished(SSL_HANDSHAKE *hs) {
David Benjaminc3c88822016-11-14 10:32:04 +0900481 SSL *const ssl = hs->ssl;
David Benjamin0f24bed2017-01-12 19:46:50 -0500482 if (!tls13_add_finished(hs) ||
David Benjamin25ac2512017-01-12 19:31:28 -0500483 /* Update the secret to the master secret and derive traffic keys. */
484 !tls13_advance_key_schedule(hs, kZeroes, hs->hash_len) ||
David Benjamin6e4fc332016-11-17 16:43:08 +0900485 !tls13_derive_application_secrets(hs) ||
Steven Valdeza833c352016-11-01 13:39:36 -0400486 !tls13_set_traffic_key(ssl, evp_aead_seal, hs->server_traffic_secret_0,
487 hs->hash_len)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400488 return ssl_hs_error;
489 }
490
David Benjamin3977f302016-12-11 13:30:41 -0500491 hs->tls13_state = state_process_client_certificate;
David Benjaminf2401eb2016-07-18 22:25:05 +0200492 return ssl_hs_flush_and_read_message;
Steven Valdez143e8b32016-07-11 13:19:03 -0400493}
494
David Benjaminc3c88822016-11-14 10:32:04 +0900495static enum ssl_hs_wait_t do_process_client_certificate(SSL_HANDSHAKE *hs) {
496 SSL *const ssl = hs->ssl;
497 if (!hs->cert_request) {
Adam Langley37646832016-08-01 16:16:46 -0700498 /* OpenSSL returns X509_V_OK when no certificates are requested. This is
David Benjamindd634eb2016-08-18 16:40:28 -0400499 * classed by them as a bug, but it's assumed by at least NGINX. */
David Benjamin45738dd2017-02-09 20:01:26 -0500500 hs->new_session->verify_result = X509_V_OK;
Adam Langley37646832016-08-01 16:16:46 -0700501
Steven Valdez143e8b32016-07-11 13:19:03 -0400502 /* Skip this state. */
David Benjamin3977f302016-12-11 13:30:41 -0500503 hs->tls13_state = state_process_channel_id;
Steven Valdez143e8b32016-07-11 13:19:03 -0400504 return ssl_hs_ok;
505 }
506
David Benjamin4087df92016-08-01 20:16:31 -0400507 const int allow_anonymous =
508 (ssl->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) == 0;
509
David Benjamin276b7e82017-01-21 14:13:39 -0500510 if (!ssl_check_message_type(ssl, SSL3_MT_CERTIFICATE) ||
Adam Langley0c294252016-12-12 11:46:09 -0800511 !tls13_process_certificate(hs, allow_anonymous) ||
Steven Valdez908ac192017-01-12 13:17:07 -0500512 !ssl_hash_current_message(hs)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400513 return ssl_hs_error;
514 }
515
David Benjamin3977f302016-12-11 13:30:41 -0500516 hs->tls13_state = state_process_client_certificate_verify;
Steven Valdez143e8b32016-07-11 13:19:03 -0400517 return ssl_hs_read_message;
518}
519
520static enum ssl_hs_wait_t do_process_client_certificate_verify(
David Benjaminc3c88822016-11-14 10:32:04 +0900521 SSL_HANDSHAKE *hs) {
522 SSL *const ssl = hs->ssl;
David Benjamin45738dd2017-02-09 20:01:26 -0500523 if (sk_CRYPTO_BUFFER_num(hs->new_session->certs) == 0) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400524 /* Skip this state. */
David Benjamin3977f302016-12-11 13:30:41 -0500525 hs->tls13_state = state_process_channel_id;
Steven Valdez143e8b32016-07-11 13:19:03 -0400526 return ssl_hs_ok;
527 }
528
David Benjamin276b7e82017-01-21 14:13:39 -0500529 if (!ssl_check_message_type(ssl, SSL3_MT_CERTIFICATE_VERIFY) ||
Adam Langley0c294252016-12-12 11:46:09 -0800530 !tls13_process_certificate_verify(hs) ||
Steven Valdez908ac192017-01-12 13:17:07 -0500531 !ssl_hash_current_message(hs)) {
David Benjamin6929f272016-11-16 19:10:08 +0900532 return ssl_hs_error;
Steven Valdez143e8b32016-07-11 13:19:03 -0400533 }
534
David Benjamin3977f302016-12-11 13:30:41 -0500535 hs->tls13_state = state_process_channel_id;
Nick Harper60a85cb2016-09-23 16:25:11 -0700536 return ssl_hs_read_message;
537}
538
David Benjaminc3c88822016-11-14 10:32:04 +0900539static enum ssl_hs_wait_t do_process_channel_id(SSL_HANDSHAKE *hs) {
Steven Valdez908ac192017-01-12 13:17:07 -0500540 if (!hs->ssl->s3->tlsext_channel_id_valid) {
David Benjamin3977f302016-12-11 13:30:41 -0500541 hs->tls13_state = state_process_client_finished;
Nick Harper60a85cb2016-09-23 16:25:11 -0700542 return ssl_hs_ok;
543 }
544
Steven Valdez908ac192017-01-12 13:17:07 -0500545 if (!ssl_check_message_type(hs->ssl, SSL3_MT_CHANNEL_ID) ||
546 !tls1_verify_channel_id(hs) ||
547 !ssl_hash_current_message(hs)) {
Nick Harper60a85cb2016-09-23 16:25:11 -0700548 return ssl_hs_error;
549 }
550
David Benjamin3977f302016-12-11 13:30:41 -0500551 hs->tls13_state = state_process_client_finished;
Steven Valdez143e8b32016-07-11 13:19:03 -0400552 return ssl_hs_read_message;
553}
554
David Benjaminc3c88822016-11-14 10:32:04 +0900555static enum ssl_hs_wait_t do_process_client_finished(SSL_HANDSHAKE *hs) {
556 SSL *const ssl = hs->ssl;
David Benjamin276b7e82017-01-21 14:13:39 -0500557 if (!ssl_check_message_type(ssl, SSL3_MT_FINISHED) ||
David Benjamin6e4fc332016-11-17 16:43:08 +0900558 !tls13_process_finished(hs) ||
Steven Valdez908ac192017-01-12 13:17:07 -0500559 !ssl_hash_current_message(hs) ||
Steven Valdez143e8b32016-07-11 13:19:03 -0400560 /* evp_aead_seal keys have already been switched. */
Steven Valdeza833c352016-11-01 13:39:36 -0400561 !tls13_set_traffic_key(ssl, evp_aead_open, hs->client_traffic_secret_0,
562 hs->hash_len) ||
David Benjamin6e4fc332016-11-17 16:43:08 +0900563 !tls13_derive_resumption_secret(hs)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400564 return ssl_hs_error;
565 }
566
David Benjamin613fe3b2016-07-22 17:39:29 +0200567 ssl->method->received_flight(ssl);
David Benjamin123db572016-11-03 16:59:25 -0400568
David Benjamin17b30832017-01-28 14:00:32 -0500569 /* Rebase the session timestamp so that it is measured from ticket
David Benjamin123db572016-11-03 16:59:25 -0400570 * issuance. */
David Benjamin45738dd2017-02-09 20:01:26 -0500571 ssl_session_rebase_time(ssl, hs->new_session);
David Benjamin3977f302016-12-11 13:30:41 -0500572 hs->tls13_state = state_send_new_session_ticket;
Steven Valdez143e8b32016-07-11 13:19:03 -0400573 return ssl_hs_ok;
574}
575
David Benjaminc3c88822016-11-14 10:32:04 +0900576static enum ssl_hs_wait_t do_send_new_session_ticket(SSL_HANDSHAKE *hs) {
David Benjamin25ac2512017-01-12 19:31:28 -0500577 /* TLS 1.3 recommends single-use tickets, so issue multiple tickets in case the
578 * client makes several connections before getting a renewal. */
579 static const int kNumTickets = 2;
580
David Benjaminc3c88822016-11-14 10:32:04 +0900581 SSL *const ssl = hs->ssl;
Steven Valdeza833c352016-11-01 13:39:36 -0400582 /* If the client doesn't accept resumption with PSK_DHE_KE, don't send a
583 * session ticket. */
584 if (!hs->accept_psk_mode) {
David Benjamin3977f302016-12-11 13:30:41 -0500585 hs->tls13_state = state_done;
Steven Valdeza833c352016-11-01 13:39:36 -0400586 return ssl_hs_ok;
587 }
588
David Benjamin45738dd2017-02-09 20:01:26 -0500589 SSL_SESSION *session = hs->new_session;
David Benjamin25ac2512017-01-12 19:31:28 -0500590 CBB cbb;
591 CBB_zero(&cbb);
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400592
David Benjamin25ac2512017-01-12 19:31:28 -0500593 for (int i = 0; i < kNumTickets; i++) {
594 if (!RAND_bytes((uint8_t *)&session->ticket_age_add, 4)) {
595 goto err;
596 }
David Benjamin35ac5b72017-03-03 15:05:56 -0500597 session->ticket_age_add_valid = 1;
David Benjamin1a5e8ec2016-10-07 15:19:18 -0400598
David Benjamin25ac2512017-01-12 19:31:28 -0500599 CBB body, ticket, extensions;
600 if (!ssl->method->init_message(ssl, &cbb, &body,
601 SSL3_MT_NEW_SESSION_TICKET) ||
602 !CBB_add_u32(&body, session->timeout) ||
603 !CBB_add_u32(&body, session->ticket_age_add) ||
604 !CBB_add_u16_length_prefixed(&body, &ticket) ||
605 !ssl_encrypt_ticket(ssl, &ticket, session) ||
606 !CBB_add_u16_length_prefixed(&body, &extensions)) {
607 goto err;
608 }
Steven Valdez08b65f42016-12-07 15:29:45 -0500609
David Benjamin25ac2512017-01-12 19:31:28 -0500610 if (ssl->ctx->enable_early_data) {
611 session->ticket_max_early_data = kMaxEarlyDataAccepted;
612
613 CBB early_data_info;
614 if (!CBB_add_u16(&extensions, TLSEXT_TYPE_ticket_early_data_info) ||
615 !CBB_add_u16_length_prefixed(&extensions, &early_data_info) ||
616 !CBB_add_u32(&early_data_info, session->ticket_max_early_data) ||
617 !CBB_flush(&extensions)) {
618 goto err;
619 }
620 }
621
622 /* Add a fake extension. See draft-davidben-tls-grease-01. */
623 if (!CBB_add_u16(&extensions,
624 ssl_get_grease_value(ssl, ssl_grease_ticket_extension)) ||
625 !CBB_add_u16(&extensions, 0 /* empty */)) {
626 goto err;
627 }
628
629 if (!ssl_add_message_cbb(ssl, &cbb)) {
Steven Valdez08b65f42016-12-07 15:29:45 -0500630 goto err;
631 }
632 }
633
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400634 hs->session_tickets_sent++;
David Benjamin25ac2512017-01-12 19:31:28 -0500635 hs->tls13_state = state_done;
636 return ssl_hs_flush;
David Benjamin1a5e8ec2016-10-07 15:19:18 -0400637
638err:
639 CBB_cleanup(&cbb);
640 return ssl_hs_error;
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400641}
642
David Benjaminc3c88822016-11-14 10:32:04 +0900643enum ssl_hs_wait_t tls13_server_handshake(SSL_HANDSHAKE *hs) {
David Benjamin3977f302016-12-11 13:30:41 -0500644 while (hs->tls13_state != state_done) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400645 enum ssl_hs_wait_t ret = ssl_hs_error;
David Benjamin3977f302016-12-11 13:30:41 -0500646 enum server_hs_state_t state = hs->tls13_state;
Steven Valdez143e8b32016-07-11 13:19:03 -0400647 switch (state) {
David Benjamin25fe85b2016-08-09 20:00:32 -0400648 case state_select_parameters:
David Benjaminc3c88822016-11-14 10:32:04 +0900649 ret = do_select_parameters(hs);
David Benjamin25fe85b2016-08-09 20:00:32 -0400650 break;
Steven Valdez5440fe02016-07-18 12:40:30 -0400651 case state_send_hello_retry_request:
David Benjaminc3c88822016-11-14 10:32:04 +0900652 ret = do_send_hello_retry_request(hs);
Steven Valdez5440fe02016-07-18 12:40:30 -0400653 break;
Steven Valdez5440fe02016-07-18 12:40:30 -0400654 case state_process_second_client_hello:
David Benjaminc3c88822016-11-14 10:32:04 +0900655 ret = do_process_second_client_hello(hs);
Steven Valdez5440fe02016-07-18 12:40:30 -0400656 break;
Steven Valdez143e8b32016-07-11 13:19:03 -0400657 case state_send_server_hello:
David Benjaminc3c88822016-11-14 10:32:04 +0900658 ret = do_send_server_hello(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400659 break;
Steven Valdez143e8b32016-07-11 13:19:03 -0400660 case state_send_server_certificate_verify:
David Benjaminc3c88822016-11-14 10:32:04 +0900661 ret = do_send_server_certificate_verify(hs, 1 /* first run */);
Steven Valdez143e8b32016-07-11 13:19:03 -0400662 break;
663 case state_complete_server_certificate_verify:
David Benjaminc3c88822016-11-14 10:32:04 +0900664 ret = do_send_server_certificate_verify(hs, 0 /* complete */);
Steven Valdez143e8b32016-07-11 13:19:03 -0400665 break;
666 case state_send_server_finished:
David Benjaminc3c88822016-11-14 10:32:04 +0900667 ret = do_send_server_finished(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400668 break;
Steven Valdez143e8b32016-07-11 13:19:03 -0400669 case state_process_client_certificate:
David Benjaminc3c88822016-11-14 10:32:04 +0900670 ret = do_process_client_certificate(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400671 break;
672 case state_process_client_certificate_verify:
David Benjaminc3c88822016-11-14 10:32:04 +0900673 ret = do_process_client_certificate_verify(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400674 break;
Nick Harper60a85cb2016-09-23 16:25:11 -0700675 case state_process_channel_id:
David Benjaminc3c88822016-11-14 10:32:04 +0900676 ret = do_process_channel_id(hs);
Nick Harper60a85cb2016-09-23 16:25:11 -0700677 break;
Steven Valdez143e8b32016-07-11 13:19:03 -0400678 case state_process_client_finished:
David Benjaminc3c88822016-11-14 10:32:04 +0900679 ret = do_process_client_finished(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400680 break;
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400681 case state_send_new_session_ticket:
David Benjaminc3c88822016-11-14 10:32:04 +0900682 ret = do_send_new_session_ticket(hs);
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400683 break;
Steven Valdez143e8b32016-07-11 13:19:03 -0400684 case state_done:
685 ret = ssl_hs_ok;
686 break;
687 }
688
689 if (ret != ssl_hs_ok) {
690 return ret;
691 }
692 }
693
694 return ssl_hs_ok;
695}