blob: 979d8cc7a4e8ecf2230669369d3cb690efdf548b [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
28#include "internal.h"
29
30
31enum server_hs_state_t {
32 state_process_client_hello = 0,
David Benjamin25fe85b2016-08-09 20:00:32 -040033 state_select_parameters,
Steven Valdez5440fe02016-07-18 12:40:30 -040034 state_send_hello_retry_request,
35 state_flush_hello_retry_request,
36 state_process_second_client_hello,
Steven Valdez143e8b32016-07-11 13:19:03 -040037 state_send_server_hello,
38 state_send_encrypted_extensions,
39 state_send_certificate_request,
40 state_send_server_certificate,
41 state_send_server_certificate_verify,
42 state_complete_server_certificate_verify,
43 state_send_server_finished,
44 state_flush,
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,
David Benjamin0a011fc2016-11-03 17:19:16 -040050 state_flush_new_session_tickets,
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
Steven Valdez5440fe02016-07-18 12:40:30 -040056static int resolve_ecdhe_secret(SSL *ssl, int *out_need_retry,
57 struct ssl_early_callback_ctx *early_ctx) {
58 *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 Benjamincec73442016-08-02 17:41:33 -040062 if (!ssl_early_callback_get_extension(early_ctx, &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;
Steven Valdez7259f2f2016-08-02 16:55:05 -040073 if (!ssl_ext_key_share_parse_clienthello(ssl, &found_key_share, &dhe_secret,
74 &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
85 int ok = tls13_advance_key_schedule(ssl, dhe_secret, dhe_secret_len);
86 OPENSSL_free(dhe_secret);
87 return ok;
88}
89
Steven Valdez143e8b32016-07-11 13:19:03 -040090static enum ssl_hs_wait_t do_process_client_hello(SSL *ssl, SSL_HANDSHAKE *hs) {
91 if (!tls13_check_message_type(ssl, SSL3_MT_CLIENT_HELLO)) {
92 return ssl_hs_error;
93 }
94
David Benjamine14ff062016-08-09 16:21:24 -040095 struct ssl_early_callback_ctx client_hello;
96 if (!ssl_early_callback_init(ssl, &client_hello, ssl->init_msg,
David Benjamind7573dc2016-07-20 19:05:22 +020097 ssl->init_num)) {
Steven Valdez143e8b32016-07-11 13:19:03 -040098 OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_PARSE_FAILED);
99 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
100 return ssl_hs_error;
101 }
102
Steven Valdez143e8b32016-07-11 13:19:03 -0400103 assert(ssl->s3->have_version);
104
105 /* Load the client random. */
David Benjamine14ff062016-08-09 16:21:24 -0400106 if (client_hello.random_len != SSL3_RANDOM_SIZE) {
107 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
David Benjamin6929f272016-11-16 19:10:08 +0900108 return ssl_hs_error;
David Benjamine14ff062016-08-09 16:21:24 -0400109 }
110 memcpy(ssl->s3->client_random, client_hello.random, client_hello.random_len);
Steven Valdez143e8b32016-07-11 13:19:03 -0400111
Steven Valdez4aa154e2016-07-29 14:32:55 -0400112 uint8_t alert = SSL_AD_DECODE_ERROR;
Steven Valdeza833c352016-11-01 13:39:36 -0400113 CBS psk_key_exchange_modes;
114 if (ssl_early_callback_get_extension(&client_hello, &psk_key_exchange_modes,
115 TLSEXT_TYPE_psk_key_exchange_modes) &&
116 !ssl_ext_psk_key_exchange_modes_parse_clienthello(
117 ssl, &alert, &psk_key_exchange_modes)) {
Steven Valdez4aa154e2016-07-29 14:32:55 -0400118 ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
David Benjamin6929f272016-11-16 19:10:08 +0900119 return ssl_hs_error;
Steven Valdez4aa154e2016-07-29 14:32:55 -0400120 }
121
Steven Valdeza833c352016-11-01 13:39:36 -0400122 SSL_SESSION *session = NULL;
123 CBS binders;
124 if (hs->accept_psk_mode) {
125 CBS pre_shared_key;
126 if (ssl_early_callback_get_extension(&client_hello, &pre_shared_key,
127 TLSEXT_TYPE_pre_shared_key)) {
128 /* Verify that the pre_shared_key extension is the last extension in
129 * ClientHello. */
130 if (CBS_data(&pre_shared_key) + CBS_len(&pre_shared_key) !=
131 client_hello.extensions + client_hello.extensions_len) {
132 OPENSSL_PUT_ERROR(SSL, SSL_R_PRE_SHARED_KEY_MUST_BE_LAST);
133 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
David Benjamin6929f272016-11-16 19:10:08 +0900134 return ssl_hs_error;
Steven Valdeza833c352016-11-01 13:39:36 -0400135 }
136
137 if (!ssl_ext_pre_shared_key_parse_clienthello(ssl, &session, &binders,
138 &alert, &pre_shared_key)) {
139 ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
David Benjamin6929f272016-11-16 19:10:08 +0900140 return ssl_hs_error;
Steven Valdeza833c352016-11-01 13:39:36 -0400141 }
142 }
143 }
144
Steven Valdez4aa154e2016-07-29 14:32:55 -0400145 if (session != NULL &&
David Benjamin75f99142016-11-12 12:36:06 +0900146 !ssl_session_is_resumable(ssl, session)) {
Steven Valdez4aa154e2016-07-29 14:32:55 -0400147 SSL_SESSION_free(session);
148 session = NULL;
149 }
150
151 if (session == NULL) {
152 if (!ssl_get_new_session(ssl, 1 /* server */)) {
153 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
154 return ssl_hs_error;
155 }
156 } else {
Steven Valdeza833c352016-11-01 13:39:36 -0400157 /* Check the PSK binder. */
158 if (!tls13_verify_psk_binder(ssl, session, &binders)) {
159 SSL_SESSION_free(session);
160 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR);
161 return ssl_hs_error;
162 }
163
Steven Valdez4aa154e2016-07-29 14:32:55 -0400164 /* Only authentication information carries over in TLS 1.3. */
165 ssl->s3->new_session = SSL_SESSION_dup(session, SSL_SESSION_DUP_AUTH_ONLY);
166 if (ssl->s3->new_session == NULL) {
167 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
168 return ssl_hs_error;
169 }
170 ssl->s3->session_reused = 1;
Steven Valdez4aa154e2016-07-29 14:32:55 -0400171 SSL_SESSION_free(session);
Steven Valdez143e8b32016-07-11 13:19:03 -0400172 }
173
174 if (ssl->ctx->dos_protection_cb != NULL &&
David Benjamine14ff062016-08-09 16:21:24 -0400175 ssl->ctx->dos_protection_cb(&client_hello) == 0) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400176 /* Connection rejected for DOS reasons. */
177 OPENSSL_PUT_ERROR(SSL, SSL_R_CONNECTION_REJECTED);
David Benjamin2c66e072016-09-16 15:58:00 -0400178 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
Steven Valdez143e8b32016-07-11 13:19:03 -0400179 return ssl_hs_error;
180 }
181
Steven Valdez143e8b32016-07-11 13:19:03 -0400182 /* TLS 1.3 requires the peer only advertise the null compression. */
David Benjamine14ff062016-08-09 16:21:24 -0400183 if (client_hello.compression_methods_len != 1 ||
184 client_hello.compression_methods[0] != 0) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400185 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_COMPRESSION_LIST);
186 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
187 return ssl_hs_error;
188 }
189
190 /* TLS extensions. */
David Benjamine14ff062016-08-09 16:21:24 -0400191 if (!ssl_parse_clienthello_tlsext(ssl, &client_hello)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400192 OPENSSL_PUT_ERROR(SSL, SSL_R_PARSE_TLSEXT);
193 return ssl_hs_error;
194 }
195
David Benjamin25fe85b2016-08-09 20:00:32 -0400196 hs->state = state_select_parameters;
197 return ssl_hs_ok;
198}
199
David Benjaminabbbee12016-10-31 19:20:42 -0400200static const SSL_CIPHER *choose_tls13_cipher(
201 const SSL *ssl, const struct ssl_early_callback_ctx *client_hello) {
202 if (client_hello->cipher_suites_len % 2 != 0) {
203 return NULL;
204 }
205
206 CBS cipher_suites;
207 CBS_init(&cipher_suites, client_hello->cipher_suites,
208 client_hello->cipher_suites_len);
209
210 const int aes_is_fine = EVP_has_aes_hardware();
211
212 const SSL_CIPHER *best = NULL;
213 while (CBS_len(&cipher_suites) > 0) {
214 uint16_t cipher_suite;
215 if (!CBS_get_u16(&cipher_suites, &cipher_suite)) {
216 return NULL;
217 }
218
219 const SSL_CIPHER *candidate = SSL_get_cipher_by_value(cipher_suite);
220 if (candidate == NULL || !ssl_is_valid_cipher(ssl, candidate)) {
221 continue;
222 }
223
224 /* TLS 1.3 removes legacy ciphers, so honor the client order, but prefer
225 * ChaCha20 if we do not have AES hardware. */
226 if (aes_is_fine) {
227 return candidate;
228 }
229
230 if (candidate->algorithm_enc == SSL_CHACHA20POLY1305) {
231 return candidate;
232 }
233
234 if (best == NULL) {
235 best = candidate;
236 }
237 }
238
239 return best;
240}
241
David Benjamin25fe85b2016-08-09 20:00:32 -0400242static enum ssl_hs_wait_t do_select_parameters(SSL *ssl, SSL_HANDSHAKE *hs) {
Steven Valdez4aa154e2016-07-29 14:32:55 -0400243 if (!ssl->s3->session_reused) {
244 /* Call |cert_cb| to update server certificates if required. */
245 if (ssl->cert->cert_cb != NULL) {
246 int rv = ssl->cert->cert_cb(ssl, ssl->cert->cert_cb_arg);
247 if (rv == 0) {
248 OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_CB_ERROR);
249 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
250 return ssl_hs_error;
251 }
252 if (rv < 0) {
253 hs->state = state_select_parameters;
254 return ssl_hs_x509_lookup;
255 }
Steven Valdez143e8b32016-07-11 13:19:03 -0400256 }
257 }
258
David Benjamin25fe85b2016-08-09 20:00:32 -0400259 struct ssl_early_callback_ctx client_hello;
260 if (!ssl_early_callback_init(ssl, &client_hello, ssl->init_msg,
261 ssl->init_num)) {
262 OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_PARSE_FAILED);
263 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
264 return ssl_hs_error;
265 }
266
David Benjamin75f99142016-11-12 12:36:06 +0900267 if (ssl->s3->session_reused) {
268 /* Clients may not offer sessions containing unsupported ciphers. */
269 if (!ssl_client_cipher_list_contains_cipher(
270 &client_hello,
271 (uint16_t)SSL_CIPHER_get_id(ssl->s3->new_session->cipher))) {
272 OPENSSL_PUT_ERROR(SSL, SSL_R_REQUIRED_CIPHER_MISSING);
273 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
274 return ssl_hs_error;
275 }
276 } else {
David Benjaminabbbee12016-10-31 19:20:42 -0400277 const SSL_CIPHER *cipher = choose_tls13_cipher(ssl, &client_hello);
Steven Valdez4aa154e2016-07-29 14:32:55 -0400278 if (cipher == NULL) {
279 OPENSSL_PUT_ERROR(SSL, SSL_R_NO_SHARED_CIPHER);
280 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
281 return ssl_hs_error;
282 }
Steven Valdez143e8b32016-07-11 13:19:03 -0400283
Steven Valdez4aa154e2016-07-29 14:32:55 -0400284 ssl->s3->new_session->cipher = cipher;
Steven Valdez4aa154e2016-07-29 14:32:55 -0400285 }
Steven Valdez143e8b32016-07-11 13:19:03 -0400286
Steven Valdez803c77a2016-09-06 14:13:43 -0400287 ssl->s3->tmp.new_cipher = ssl->s3->new_session->cipher;
David Benjamin613fe3b2016-07-22 17:39:29 +0200288 ssl->method->received_flight(ssl);
289
David Benjamin9ef31f02016-10-31 18:01:13 -0400290 /* Resolve ALPN after the cipher suite is selected. HTTP/2 negotiation depends
291 * on the cipher suite. */
292 uint8_t alert;
293 if (!ssl_negotiate_alpn(ssl, &alert, &client_hello)) {
294 ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
295 return ssl_hs_error;
296 }
Steven Valdez803c77a2016-09-06 14:13:43 -0400297
298 /* The PRF hash is now known. */
299 size_t hash_len =
Steven Valdez143e8b32016-07-11 13:19:03 -0400300 EVP_MD_size(ssl_get_handshake_digest(ssl_get_algorithm_prf(ssl)));
Steven Valdez803c77a2016-09-06 14:13:43 -0400301
302 /* Derive resumption material. */
Steven Valdez803c77a2016-09-06 14:13:43 -0400303 uint8_t psk_secret[EVP_MAX_MD_SIZE] = {0};
Steven Valdez4aa154e2016-07-29 14:32:55 -0400304 if (ssl->s3->session_reused) {
Steven Valdeza833c352016-11-01 13:39:36 -0400305 if (hash_len != (size_t) ssl->s3->new_session->master_key_length) {
Steven Valdez4aa154e2016-07-29 14:32:55 -0400306 return ssl_hs_error;
307 }
Steven Valdeza833c352016-11-01 13:39:36 -0400308 memcpy(psk_secret, ssl->s3->new_session->master_key, hash_len);
Steven Valdez143e8b32016-07-11 13:19:03 -0400309 }
310
Steven Valdez803c77a2016-09-06 14:13:43 -0400311 /* Set up the key schedule, hash in the ClientHello, and incorporate the PSK
312 * into the running secret. */
Steven Valdeza833c352016-11-01 13:39:36 -0400313 if (!tls13_init_key_schedule(ssl) ||
Steven Valdez803c77a2016-09-06 14:13:43 -0400314 !tls13_advance_key_schedule(ssl, psk_secret, hash_len)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400315 return ssl_hs_error;
316 }
317
318 /* Resolve ECDHE and incorporate it into the secret. */
Steven Valdez5440fe02016-07-18 12:40:30 -0400319 int need_retry;
David Benjamine14ff062016-08-09 16:21:24 -0400320 if (!resolve_ecdhe_secret(ssl, &need_retry, &client_hello)) {
Steven Valdez5440fe02016-07-18 12:40:30 -0400321 if (need_retry) {
322 hs->state = state_send_hello_retry_request;
323 return ssl_hs_ok;
Steven Valdez143e8b32016-07-11 13:19:03 -0400324 }
Steven Valdez5440fe02016-07-18 12:40:30 -0400325 return ssl_hs_error;
326 }
Steven Valdez143e8b32016-07-11 13:19:03 -0400327
Steven Valdez5440fe02016-07-18 12:40:30 -0400328 hs->state = state_send_server_hello;
329 return ssl_hs_ok;
330}
Steven Valdez143e8b32016-07-11 13:19:03 -0400331
Steven Valdez5440fe02016-07-18 12:40:30 -0400332static enum ssl_hs_wait_t do_send_hello_retry_request(SSL *ssl,
333 SSL_HANDSHAKE *hs) {
334 CBB cbb, body, extensions;
335 uint16_t group_id;
336 if (!ssl->method->init_message(ssl, &cbb, &body,
337 SSL3_MT_HELLO_RETRY_REQUEST) ||
338 !CBB_add_u16(&body, ssl->version) ||
Steven Valdez5440fe02016-07-18 12:40:30 -0400339 !tls1_get_shared_group(ssl, &group_id) ||
Steven Valdez5440fe02016-07-18 12:40:30 -0400340 !CBB_add_u16_length_prefixed(&body, &extensions) ||
David Benjamin3baa6e12016-10-07 21:10:38 -0400341 !CBB_add_u16(&extensions, TLSEXT_TYPE_key_share) ||
342 !CBB_add_u16(&extensions, 2 /* length */) ||
343 !CBB_add_u16(&extensions, group_id) ||
Steven Valdez5eead162016-11-11 22:23:25 -0500344 !ssl_complete_message(ssl, &cbb)) {
Steven Valdez5440fe02016-07-18 12:40:30 -0400345 CBB_cleanup(&cbb);
346 return ssl_hs_error;
347 }
348
349 hs->state = state_flush_hello_retry_request;
350 return ssl_hs_write_message;
351}
352
353static enum ssl_hs_wait_t do_flush_hello_retry_request(SSL *ssl,
354 SSL_HANDSHAKE *hs) {
355 hs->state = state_process_second_client_hello;
356 return ssl_hs_flush_and_read_message;
357}
358
359static enum ssl_hs_wait_t do_process_second_client_hello(SSL *ssl,
360 SSL_HANDSHAKE *hs) {
361 if (!tls13_check_message_type(ssl, SSL3_MT_CLIENT_HELLO)) {
362 return ssl_hs_error;
363 }
364
David Benjamine14ff062016-08-09 16:21:24 -0400365 struct ssl_early_callback_ctx client_hello;
366 if (!ssl_early_callback_init(ssl, &client_hello, ssl->init_msg,
David Benjamind7573dc2016-07-20 19:05:22 +0200367 ssl->init_num)) {
Steven Valdez5440fe02016-07-18 12:40:30 -0400368 OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_PARSE_FAILED);
369 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
370 return ssl_hs_error;
371 }
372
373 int need_retry;
David Benjamine14ff062016-08-09 16:21:24 -0400374 if (!resolve_ecdhe_secret(ssl, &need_retry, &client_hello)) {
Steven Valdez5440fe02016-07-18 12:40:30 -0400375 if (need_retry) {
376 /* Only send one HelloRetryRequest. */
377 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
378 OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CURVE);
Steven Valdez143e8b32016-07-11 13:19:03 -0400379 }
Steven Valdez5440fe02016-07-18 12:40:30 -0400380 return ssl_hs_error;
381 }
382
David Benjaminced94792016-11-14 17:12:11 +0900383 if (!ssl_hash_current_message(ssl)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400384 return ssl_hs_error;
385 }
386
David Benjamin613fe3b2016-07-22 17:39:29 +0200387 ssl->method->received_flight(ssl);
Steven Valdez143e8b32016-07-11 13:19:03 -0400388 hs->state = state_send_server_hello;
389 return ssl_hs_ok;
390}
391
392static enum ssl_hs_wait_t do_send_server_hello(SSL *ssl, SSL_HANDSHAKE *hs) {
393 CBB cbb, body, extensions;
394 if (!ssl->method->init_message(ssl, &cbb, &body, SSL3_MT_SERVER_HELLO) ||
395 !CBB_add_u16(&body, ssl->version) ||
396 !RAND_bytes(ssl->s3->server_random, sizeof(ssl->s3->server_random)) ||
397 !CBB_add_bytes(&body, ssl->s3->server_random, SSL3_RANDOM_SIZE) ||
398 !CBB_add_u16(&body, ssl_cipher_get_value(ssl->s3->tmp.new_cipher)) ||
399 !CBB_add_u16_length_prefixed(&body, &extensions) ||
Steven Valdez4aa154e2016-07-29 14:32:55 -0400400 !ssl_ext_pre_shared_key_add_serverhello(ssl, &extensions) ||
Steven Valdeza833c352016-11-01 13:39:36 -0400401 !ssl_ext_key_share_add_serverhello(ssl, &extensions) ||
402 !ssl_complete_message(ssl, &cbb)) {
Steven Valdez803c77a2016-09-06 14:13:43 -0400403 goto err;
Steven Valdez143e8b32016-07-11 13:19:03 -0400404 }
405
406 hs->state = state_send_encrypted_extensions;
407 return ssl_hs_write_message;
Steven Valdez803c77a2016-09-06 14:13:43 -0400408
409err:
410 CBB_cleanup(&cbb);
411 return ssl_hs_error;
Steven Valdez143e8b32016-07-11 13:19:03 -0400412}
413
414static enum ssl_hs_wait_t do_send_encrypted_extensions(SSL *ssl,
415 SSL_HANDSHAKE *hs) {
416 if (!tls13_set_handshake_traffic(ssl)) {
417 return ssl_hs_error;
418 }
419
420 CBB cbb, body;
421 if (!ssl->method->init_message(ssl, &cbb, &body,
422 SSL3_MT_ENCRYPTED_EXTENSIONS) ||
423 !ssl_add_serverhello_tlsext(ssl, &body) ||
Steven Valdez5eead162016-11-11 22:23:25 -0500424 !ssl_complete_message(ssl, &cbb)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400425 CBB_cleanup(&cbb);
426 return ssl_hs_error;
427 }
428
429 hs->state = state_send_certificate_request;
430 return ssl_hs_write_message;
431}
432
433static enum ssl_hs_wait_t do_send_certificate_request(SSL *ssl,
434 SSL_HANDSHAKE *hs) {
435 /* Determine whether to request a client certificate. */
David Benjamina0486782016-10-06 19:11:32 -0400436 ssl->s3->hs->cert_request = !!(ssl->verify_mode & SSL_VERIFY_PEER);
Steven Valdez803c77a2016-09-06 14:13:43 -0400437 /* CertificateRequest may only be sent in non-resumption handshakes. */
438 if (ssl->s3->session_reused) {
David Benjamina0486782016-10-06 19:11:32 -0400439 ssl->s3->hs->cert_request = 0;
Steven Valdez143e8b32016-07-11 13:19:03 -0400440 }
441
David Benjamina0486782016-10-06 19:11:32 -0400442 if (!ssl->s3->hs->cert_request) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400443 /* Skip this state. */
444 hs->state = state_send_server_certificate;
445 return ssl_hs_ok;
446 }
447
448 CBB cbb, body, sigalgs_cbb;
449 if (!ssl->method->init_message(ssl, &cbb, &body,
450 SSL3_MT_CERTIFICATE_REQUEST) ||
451 !CBB_add_u8(&body, 0 /* no certificate_request_context. */)) {
452 goto err;
453 }
454
455 const uint16_t *sigalgs;
David Benjamin3ef76972016-10-17 17:59:54 -0400456 size_t num_sigalgs = tls12_get_verify_sigalgs(ssl, &sigalgs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400457 if (!CBB_add_u16_length_prefixed(&body, &sigalgs_cbb)) {
458 goto err;
459 }
460
David Benjamin0fc37ef2016-08-17 15:29:46 -0400461 for (size_t i = 0; i < num_sigalgs; i++) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400462 if (!CBB_add_u16(&sigalgs_cbb, sigalgs[i])) {
463 goto err;
464 }
465 }
466
467 if (!ssl_add_client_CA_list(ssl, &body) ||
468 !CBB_add_u16(&body, 0 /* empty certificate_extensions. */) ||
Steven Valdez5eead162016-11-11 22:23:25 -0500469 !ssl_complete_message(ssl, &cbb)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400470 goto err;
471 }
472
473 hs->state = state_send_server_certificate;
474 return ssl_hs_write_message;
475
476err:
477 CBB_cleanup(&cbb);
478 return ssl_hs_error;
479}
480
481static enum ssl_hs_wait_t do_send_server_certificate(SSL *ssl,
482 SSL_HANDSHAKE *hs) {
Steven Valdez803c77a2016-09-06 14:13:43 -0400483 if (ssl->s3->session_reused) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400484 hs->state = state_send_server_finished;
485 return ssl_hs_ok;
486 }
487
488 if (!ssl_has_certificate(ssl)) {
489 OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATE_SET);
490 return ssl_hs_error;
491 }
492
493 if (!tls13_prepare_certificate(ssl)) {
494 return ssl_hs_error;
495 }
496
497 hs->state = state_send_server_certificate_verify;
498 return ssl_hs_write_message;
499}
500
501static enum ssl_hs_wait_t do_send_server_certificate_verify(SSL *ssl,
502 SSL_HANDSHAKE *hs,
503 int is_first_run) {
504 switch (tls13_prepare_certificate_verify(ssl, is_first_run)) {
505 case ssl_private_key_success:
506 hs->state = state_send_server_finished;
507 return ssl_hs_write_message;
508
509 case ssl_private_key_retry:
510 hs->state = state_complete_server_certificate_verify;
511 return ssl_hs_private_key_operation;
512
513 case ssl_private_key_failure:
514 return ssl_hs_error;
515 }
516
517 assert(0);
518 return ssl_hs_error;
519}
520
521static enum ssl_hs_wait_t do_send_server_finished(SSL *ssl, SSL_HANDSHAKE *hs) {
522 if (!tls13_prepare_finished(ssl)) {
523 return ssl_hs_error;
524 }
525
526 hs->state = state_flush;
527 return ssl_hs_write_message;
528}
529
530static enum ssl_hs_wait_t do_flush(SSL *ssl, SSL_HANDSHAKE *hs) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400531 /* Update the secret to the master secret and derive traffic keys. */
Steven Valdez143e8b32016-07-11 13:19:03 -0400532 if (!tls13_advance_key_schedule(ssl, kZeroes, hs->hash_len) ||
Steven Valdeza833c352016-11-01 13:39:36 -0400533 !tls13_derive_application_secrets(ssl) ||
534 !tls13_set_traffic_key(ssl, evp_aead_seal, hs->server_traffic_secret_0,
535 hs->hash_len)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400536 return ssl_hs_error;
537 }
538
539 hs->state = state_process_client_certificate;
David Benjaminf2401eb2016-07-18 22:25:05 +0200540 return ssl_hs_flush_and_read_message;
Steven Valdez143e8b32016-07-11 13:19:03 -0400541}
542
543static enum ssl_hs_wait_t do_process_client_certificate(SSL *ssl,
544 SSL_HANDSHAKE *hs) {
David Benjamina0486782016-10-06 19:11:32 -0400545 if (!ssl->s3->hs->cert_request) {
Adam Langley37646832016-08-01 16:16:46 -0700546 /* OpenSSL returns X509_V_OK when no certificates are requested. This is
David Benjamindd634eb2016-08-18 16:40:28 -0400547 * classed by them as a bug, but it's assumed by at least NGINX. */
Adam Langley37646832016-08-01 16:16:46 -0700548 ssl->s3->new_session->verify_result = X509_V_OK;
549
Steven Valdez143e8b32016-07-11 13:19:03 -0400550 /* Skip this state. */
Nick Harper60a85cb2016-09-23 16:25:11 -0700551 hs->state = state_process_channel_id;
Steven Valdez143e8b32016-07-11 13:19:03 -0400552 return ssl_hs_ok;
553 }
554
David Benjamin4087df92016-08-01 20:16:31 -0400555 const int allow_anonymous =
556 (ssl->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) == 0;
557
Steven Valdez143e8b32016-07-11 13:19:03 -0400558 if (!tls13_check_message_type(ssl, SSL3_MT_CERTIFICATE) ||
David Benjamin4087df92016-08-01 20:16:31 -0400559 !tls13_process_certificate(ssl, allow_anonymous) ||
David Benjaminced94792016-11-14 17:12:11 +0900560 !ssl_hash_current_message(ssl)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400561 return ssl_hs_error;
562 }
563
David Benjamin3ce43892016-08-01 19:41:34 -0400564 /* For historical reasons, the server's copy of the chain does not include the
565 * leaf while the client's does. */
Adam Langleyc5ac2b62016-11-07 12:02:35 -0800566 if (sk_X509_num(ssl->s3->new_session->x509_chain) > 0) {
567 X509_free(sk_X509_shift(ssl->s3->new_session->x509_chain));
David Benjamin3ce43892016-08-01 19:41:34 -0400568 }
569
Steven Valdez143e8b32016-07-11 13:19:03 -0400570 hs->state = state_process_client_certificate_verify;
571 return ssl_hs_read_message;
572}
573
574static enum ssl_hs_wait_t do_process_client_certificate_verify(
575 SSL *ssl, SSL_HANDSHAKE *hs) {
Adam Langleyc5ac2b62016-11-07 12:02:35 -0800576 if (ssl->s3->new_session->x509_peer == NULL) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400577 /* Skip this state. */
Nick Harper60a85cb2016-09-23 16:25:11 -0700578 hs->state = state_process_channel_id;
Steven Valdez143e8b32016-07-11 13:19:03 -0400579 return ssl_hs_ok;
580 }
581
582 if (!tls13_check_message_type(ssl, SSL3_MT_CERTIFICATE_VERIFY) ||
583 !tls13_process_certificate_verify(ssl) ||
David Benjaminced94792016-11-14 17:12:11 +0900584 !ssl_hash_current_message(ssl)) {
David Benjamin6929f272016-11-16 19:10:08 +0900585 return ssl_hs_error;
Steven Valdez143e8b32016-07-11 13:19:03 -0400586 }
587
Nick Harper60a85cb2016-09-23 16:25:11 -0700588 hs->state = state_process_channel_id;
589 return ssl_hs_read_message;
590}
591
592static enum ssl_hs_wait_t do_process_channel_id(SSL *ssl, SSL_HANDSHAKE *hs) {
593 if (!ssl->s3->tlsext_channel_id_valid) {
594 hs->state = state_process_client_finished;
595 return ssl_hs_ok;
596 }
597
598 if (!tls13_check_message_type(ssl, SSL3_MT_CHANNEL_ID) ||
599 !tls1_verify_channel_id(ssl) ||
David Benjaminced94792016-11-14 17:12:11 +0900600 !ssl_hash_current_message(ssl)) {
Nick Harper60a85cb2016-09-23 16:25:11 -0700601 return ssl_hs_error;
602 }
603
Steven Valdez143e8b32016-07-11 13:19:03 -0400604 hs->state = state_process_client_finished;
605 return ssl_hs_read_message;
606}
607
608static enum ssl_hs_wait_t do_process_client_finished(SSL *ssl,
609 SSL_HANDSHAKE *hs) {
610 if (!tls13_check_message_type(ssl, SSL3_MT_FINISHED) ||
611 !tls13_process_finished(ssl) ||
David Benjaminced94792016-11-14 17:12:11 +0900612 !ssl_hash_current_message(ssl) ||
Steven Valdez143e8b32016-07-11 13:19:03 -0400613 /* evp_aead_seal keys have already been switched. */
Steven Valdeza833c352016-11-01 13:39:36 -0400614 !tls13_set_traffic_key(ssl, evp_aead_open, hs->client_traffic_secret_0,
615 hs->hash_len) ||
616 !tls13_derive_resumption_secret(ssl)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400617 return ssl_hs_error;
618 }
619
David Benjamin613fe3b2016-07-22 17:39:29 +0200620 ssl->method->received_flight(ssl);
David Benjamin123db572016-11-03 16:59:25 -0400621
622 /* Refresh the session timestamp so that it is measured from ticket
623 * issuance. */
624 ssl_session_refresh_time(ssl, ssl->s3->new_session);
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400625 hs->state = state_send_new_session_ticket;
Steven Valdez143e8b32016-07-11 13:19:03 -0400626 return ssl_hs_ok;
627}
628
David Benjamin0a011fc2016-11-03 17:19:16 -0400629/* TLS 1.3 recommends single-use tickets, so issue multiple tickets in case the
630 * client makes several connections before getting a renewal. */
631static const int kNumTickets = 2;
632
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400633static enum ssl_hs_wait_t do_send_new_session_ticket(SSL *ssl,
634 SSL_HANDSHAKE *hs) {
Steven Valdeza833c352016-11-01 13:39:36 -0400635 /* If the client doesn't accept resumption with PSK_DHE_KE, don't send a
636 * session ticket. */
637 if (!hs->accept_psk_mode) {
638 hs->state = state_done;
639 return ssl_hs_ok;
640 }
641
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400642 SSL_SESSION *session = ssl->s3->new_session;
Steven Valdeza833c352016-11-01 13:39:36 -0400643 if (!RAND_bytes((uint8_t *)&session->ticket_age_add, 4)) {
644 goto err;
645 }
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400646
Steven Valdez5b986082016-09-01 12:29:49 -0400647 /* TODO(svaldez): Add support for sending 0RTT through TicketEarlyDataInfo
648 * extension. */
649
Steven Valdeza833c352016-11-01 13:39:36 -0400650 CBB cbb, body, ticket, extensions;
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400651 if (!ssl->method->init_message(ssl, &cbb, &body,
652 SSL3_MT_NEW_SESSION_TICKET) ||
David Benjamin123db572016-11-03 16:59:25 -0400653 !CBB_add_u32(&body, session->timeout) ||
Steven Valdeza833c352016-11-01 13:39:36 -0400654 !CBB_add_u32(&body, session->ticket_age_add) ||
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400655 !CBB_add_u16_length_prefixed(&body, &ticket) ||
656 !ssl_encrypt_ticket(ssl, &ticket, session) ||
David Benjamin1a5e8ec2016-10-07 15:19:18 -0400657 !CBB_add_u16_length_prefixed(&body, &extensions)) {
658 goto err;
659 }
660
661 /* Add a fake extension. See draft-davidben-tls-grease-01. */
David Benjamin079b3942016-10-20 13:19:20 -0400662 if (!CBB_add_u16(&extensions,
663 ssl_get_grease_value(ssl, ssl_grease_ticket_extension)) ||
664 !CBB_add_u16(&extensions, 0 /* empty */)) {
665 goto err;
David Benjamin1a5e8ec2016-10-07 15:19:18 -0400666 }
667
Steven Valdez5eead162016-11-11 22:23:25 -0500668 if (!ssl_complete_message(ssl, &cbb)) {
David Benjamin1a5e8ec2016-10-07 15:19:18 -0400669 goto err;
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400670 }
671
672 hs->session_tickets_sent++;
David Benjamin0a011fc2016-11-03 17:19:16 -0400673 if (hs->session_tickets_sent >= kNumTickets) {
674 hs->state = state_flush_new_session_tickets;
675 } else {
676 hs->state = state_send_new_session_ticket;
677 }
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400678
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400679 return ssl_hs_write_message;
David Benjamin1a5e8ec2016-10-07 15:19:18 -0400680
681err:
682 CBB_cleanup(&cbb);
683 return ssl_hs_error;
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400684}
685
David Benjamin0a011fc2016-11-03 17:19:16 -0400686static enum ssl_hs_wait_t do_flush_new_session_tickets(SSL *ssl,
687 SSL_HANDSHAKE *hs) {
688 hs->state = state_done;
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400689 return ssl_hs_flush;
690}
691
Steven Valdez143e8b32016-07-11 13:19:03 -0400692enum ssl_hs_wait_t tls13_server_handshake(SSL *ssl) {
693 SSL_HANDSHAKE *hs = ssl->s3->hs;
694
695 while (hs->state != state_done) {
696 enum ssl_hs_wait_t ret = ssl_hs_error;
697 enum server_hs_state_t state = hs->state;
698 switch (state) {
699 case state_process_client_hello:
700 ret = do_process_client_hello(ssl, hs);
701 break;
David Benjamin25fe85b2016-08-09 20:00:32 -0400702 case state_select_parameters:
703 ret = do_select_parameters(ssl, hs);
704 break;
Steven Valdez5440fe02016-07-18 12:40:30 -0400705 case state_send_hello_retry_request:
706 ret = do_send_hello_retry_request(ssl, hs);
707 break;
708 case state_flush_hello_retry_request:
709 ret = do_flush_hello_retry_request(ssl, hs);
710 break;
711 case state_process_second_client_hello:
712 ret = do_process_second_client_hello(ssl, hs);
713 break;
Steven Valdez143e8b32016-07-11 13:19:03 -0400714 case state_send_server_hello:
715 ret = do_send_server_hello(ssl, hs);
716 break;
717 case state_send_encrypted_extensions:
718 ret = do_send_encrypted_extensions(ssl, hs);
719 break;
720 case state_send_certificate_request:
721 ret = do_send_certificate_request(ssl, hs);
722 break;
723 case state_send_server_certificate:
724 ret = do_send_server_certificate(ssl, hs);
725 break;
726 case state_send_server_certificate_verify:
727 ret = do_send_server_certificate_verify(ssl, hs, 1 /* first run */);
728 break;
729 case state_complete_server_certificate_verify:
730 ret = do_send_server_certificate_verify(ssl, hs, 0 /* complete */);
731 break;
732 case state_send_server_finished:
733 ret = do_send_server_finished(ssl, hs);
734 break;
735 case state_flush:
736 ret = do_flush(ssl, hs);
737 break;
Steven Valdez143e8b32016-07-11 13:19:03 -0400738 case state_process_client_certificate:
739 ret = do_process_client_certificate(ssl, hs);
740 break;
741 case state_process_client_certificate_verify:
742 ret = do_process_client_certificate_verify(ssl, hs);
743 break;
Nick Harper60a85cb2016-09-23 16:25:11 -0700744 case state_process_channel_id:
745 ret = do_process_channel_id(ssl, hs);
746 break;
Steven Valdez143e8b32016-07-11 13:19:03 -0400747 case state_process_client_finished:
748 ret = do_process_client_finished(ssl, hs);
749 break;
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400750 case state_send_new_session_ticket:
751 ret = do_send_new_session_ticket(ssl, hs);
752 break;
David Benjamin0a011fc2016-11-03 17:19:16 -0400753 case state_flush_new_session_tickets:
754 ret = do_flush_new_session_tickets(ssl, hs);
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400755 break;
Steven Valdez143e8b32016-07-11 13:19:03 -0400756 case state_done:
757 ret = ssl_hs_ok;
758 break;
759 }
760
761 if (ret != ssl_hs_ok) {
762 return ret;
763 }
764 }
765
766 return ssl_hs_ok;
767}