blob: ca7b17e4b23be35718eba889fe8aeb7c1ae39efe [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);
66 return ssl_hs_error;
67 }
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);
108 return -1;
109 }
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;
113 SSL_SESSION *session = NULL;
114 CBS pre_shared_key;
115 if (ssl_early_callback_get_extension(&client_hello, &pre_shared_key,
116 TLSEXT_TYPE_pre_shared_key) &&
117 !ssl_ext_pre_shared_key_parse_clienthello(ssl, &session, &alert,
118 &pre_shared_key)) {
119 ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
120 return 0;
121 }
122
Steven Valdez4aa154e2016-07-29 14:32:55 -0400123 if (session != NULL &&
Steven Valdez5b986082016-09-01 12:29:49 -0400124 /* Only resume if the session's version matches. */
125 (session->ssl_version != ssl->version ||
Steven Valdez803c77a2016-09-06 14:13:43 -0400126 !ssl_client_cipher_list_contains_cipher(
Steven Valdezb6b6ff32016-10-26 11:56:35 -0400127 &client_hello, (uint16_t)SSL_CIPHER_get_id(session->cipher)) ||
128 !ssl_is_valid_cipher(ssl, session->cipher))) {
Steven Valdez4aa154e2016-07-29 14:32:55 -0400129 SSL_SESSION_free(session);
130 session = NULL;
131 }
132
133 if (session == NULL) {
134 if (!ssl_get_new_session(ssl, 1 /* server */)) {
135 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
136 return ssl_hs_error;
137 }
138 } else {
139 /* Only authentication information carries over in TLS 1.3. */
140 ssl->s3->new_session = SSL_SESSION_dup(session, SSL_SESSION_DUP_AUTH_ONLY);
141 if (ssl->s3->new_session == NULL) {
142 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
143 return ssl_hs_error;
144 }
145 ssl->s3->session_reused = 1;
Steven Valdez4aa154e2016-07-29 14:32:55 -0400146 SSL_SESSION_free(session);
Steven Valdez143e8b32016-07-11 13:19:03 -0400147 }
148
149 if (ssl->ctx->dos_protection_cb != NULL &&
David Benjamine14ff062016-08-09 16:21:24 -0400150 ssl->ctx->dos_protection_cb(&client_hello) == 0) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400151 /* Connection rejected for DOS reasons. */
152 OPENSSL_PUT_ERROR(SSL, SSL_R_CONNECTION_REJECTED);
David Benjamin2c66e072016-09-16 15:58:00 -0400153 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
Steven Valdez143e8b32016-07-11 13:19:03 -0400154 return ssl_hs_error;
155 }
156
Steven Valdez143e8b32016-07-11 13:19:03 -0400157 /* TLS 1.3 requires the peer only advertise the null compression. */
David Benjamine14ff062016-08-09 16:21:24 -0400158 if (client_hello.compression_methods_len != 1 ||
159 client_hello.compression_methods[0] != 0) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400160 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_COMPRESSION_LIST);
161 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
162 return ssl_hs_error;
163 }
164
165 /* TLS extensions. */
David Benjamine14ff062016-08-09 16:21:24 -0400166 if (!ssl_parse_clienthello_tlsext(ssl, &client_hello)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400167 OPENSSL_PUT_ERROR(SSL, SSL_R_PARSE_TLSEXT);
168 return ssl_hs_error;
169 }
170
David Benjamin25fe85b2016-08-09 20:00:32 -0400171 hs->state = state_select_parameters;
172 return ssl_hs_ok;
173}
174
David Benjaminabbbee12016-10-31 19:20:42 -0400175static const SSL_CIPHER *choose_tls13_cipher(
176 const SSL *ssl, const struct ssl_early_callback_ctx *client_hello) {
177 if (client_hello->cipher_suites_len % 2 != 0) {
178 return NULL;
179 }
180
181 CBS cipher_suites;
182 CBS_init(&cipher_suites, client_hello->cipher_suites,
183 client_hello->cipher_suites_len);
184
185 const int aes_is_fine = EVP_has_aes_hardware();
186
187 const SSL_CIPHER *best = NULL;
188 while (CBS_len(&cipher_suites) > 0) {
189 uint16_t cipher_suite;
190 if (!CBS_get_u16(&cipher_suites, &cipher_suite)) {
191 return NULL;
192 }
193
194 const SSL_CIPHER *candidate = SSL_get_cipher_by_value(cipher_suite);
195 if (candidate == NULL || !ssl_is_valid_cipher(ssl, candidate)) {
196 continue;
197 }
198
199 /* TLS 1.3 removes legacy ciphers, so honor the client order, but prefer
200 * ChaCha20 if we do not have AES hardware. */
201 if (aes_is_fine) {
202 return candidate;
203 }
204
205 if (candidate->algorithm_enc == SSL_CHACHA20POLY1305) {
206 return candidate;
207 }
208
209 if (best == NULL) {
210 best = candidate;
211 }
212 }
213
214 return best;
215}
216
David Benjamin25fe85b2016-08-09 20:00:32 -0400217static enum ssl_hs_wait_t do_select_parameters(SSL *ssl, SSL_HANDSHAKE *hs) {
Steven Valdez4aa154e2016-07-29 14:32:55 -0400218 if (!ssl->s3->session_reused) {
219 /* Call |cert_cb| to update server certificates if required. */
220 if (ssl->cert->cert_cb != NULL) {
221 int rv = ssl->cert->cert_cb(ssl, ssl->cert->cert_cb_arg);
222 if (rv == 0) {
223 OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_CB_ERROR);
224 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
225 return ssl_hs_error;
226 }
227 if (rv < 0) {
228 hs->state = state_select_parameters;
229 return ssl_hs_x509_lookup;
230 }
Steven Valdez143e8b32016-07-11 13:19:03 -0400231 }
232 }
233
David Benjamin25fe85b2016-08-09 20:00:32 -0400234 struct ssl_early_callback_ctx client_hello;
235 if (!ssl_early_callback_init(ssl, &client_hello, ssl->init_msg,
236 ssl->init_num)) {
237 OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_PARSE_FAILED);
238 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
239 return ssl_hs_error;
240 }
241
Steven Valdez4aa154e2016-07-29 14:32:55 -0400242 if (!ssl->s3->session_reused) {
David Benjaminabbbee12016-10-31 19:20:42 -0400243 const SSL_CIPHER *cipher = choose_tls13_cipher(ssl, &client_hello);
Steven Valdez4aa154e2016-07-29 14:32:55 -0400244 if (cipher == NULL) {
245 OPENSSL_PUT_ERROR(SSL, SSL_R_NO_SHARED_CIPHER);
246 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
247 return ssl_hs_error;
248 }
Steven Valdez143e8b32016-07-11 13:19:03 -0400249
Steven Valdez4aa154e2016-07-29 14:32:55 -0400250 ssl->s3->new_session->cipher = cipher;
Steven Valdez4aa154e2016-07-29 14:32:55 -0400251 }
Steven Valdez143e8b32016-07-11 13:19:03 -0400252
Steven Valdez803c77a2016-09-06 14:13:43 -0400253 ssl->s3->tmp.new_cipher = ssl->s3->new_session->cipher;
David Benjamin613fe3b2016-07-22 17:39:29 +0200254 ssl->method->received_flight(ssl);
255
David Benjamin9ef31f02016-10-31 18:01:13 -0400256 /* Resolve ALPN after the cipher suite is selected. HTTP/2 negotiation depends
257 * on the cipher suite. */
258 uint8_t alert;
259 if (!ssl_negotiate_alpn(ssl, &alert, &client_hello)) {
260 ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
261 return ssl_hs_error;
262 }
Steven Valdez803c77a2016-09-06 14:13:43 -0400263
264 /* The PRF hash is now known. */
265 size_t hash_len =
Steven Valdez143e8b32016-07-11 13:19:03 -0400266 EVP_MD_size(ssl_get_handshake_digest(ssl_get_algorithm_prf(ssl)));
Steven Valdez803c77a2016-09-06 14:13:43 -0400267
268 /* Derive resumption material. */
269 uint8_t resumption_ctx[EVP_MAX_MD_SIZE] = {0};
270 uint8_t psk_secret[EVP_MAX_MD_SIZE] = {0};
Steven Valdez4aa154e2016-07-29 14:32:55 -0400271 if (ssl->s3->session_reused) {
Steven Valdez803c77a2016-09-06 14:13:43 -0400272 if (!tls13_resumption_context(ssl, resumption_ctx, hash_len,
Steven Valdez4aa154e2016-07-29 14:32:55 -0400273 ssl->s3->new_session) ||
Steven Valdez803c77a2016-09-06 14:13:43 -0400274 !tls13_resumption_psk(ssl, psk_secret, hash_len,
275 ssl->s3->new_session)) {
Steven Valdez4aa154e2016-07-29 14:32:55 -0400276 return ssl_hs_error;
277 }
Steven Valdez143e8b32016-07-11 13:19:03 -0400278 }
279
Steven Valdez803c77a2016-09-06 14:13:43 -0400280 /* Set up the key schedule, hash in the ClientHello, and incorporate the PSK
281 * into the running secret. */
282 if (!tls13_init_key_schedule(ssl, resumption_ctx, hash_len) ||
283 !tls13_advance_key_schedule(ssl, psk_secret, hash_len)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400284 return ssl_hs_error;
285 }
286
287 /* Resolve ECDHE and incorporate it into the secret. */
Steven Valdez5440fe02016-07-18 12:40:30 -0400288 int need_retry;
David Benjamine14ff062016-08-09 16:21:24 -0400289 if (!resolve_ecdhe_secret(ssl, &need_retry, &client_hello)) {
Steven Valdez5440fe02016-07-18 12:40:30 -0400290 if (need_retry) {
291 hs->state = state_send_hello_retry_request;
292 return ssl_hs_ok;
Steven Valdez143e8b32016-07-11 13:19:03 -0400293 }
Steven Valdez5440fe02016-07-18 12:40:30 -0400294 return ssl_hs_error;
295 }
Steven Valdez143e8b32016-07-11 13:19:03 -0400296
Steven Valdez5440fe02016-07-18 12:40:30 -0400297 hs->state = state_send_server_hello;
298 return ssl_hs_ok;
299}
Steven Valdez143e8b32016-07-11 13:19:03 -0400300
Steven Valdez5440fe02016-07-18 12:40:30 -0400301static enum ssl_hs_wait_t do_send_hello_retry_request(SSL *ssl,
302 SSL_HANDSHAKE *hs) {
303 CBB cbb, body, extensions;
304 uint16_t group_id;
305 if (!ssl->method->init_message(ssl, &cbb, &body,
306 SSL3_MT_HELLO_RETRY_REQUEST) ||
307 !CBB_add_u16(&body, ssl->version) ||
Steven Valdez5440fe02016-07-18 12:40:30 -0400308 !tls1_get_shared_group(ssl, &group_id) ||
Steven Valdez5440fe02016-07-18 12:40:30 -0400309 !CBB_add_u16_length_prefixed(&body, &extensions) ||
David Benjamin3baa6e12016-10-07 21:10:38 -0400310 !CBB_add_u16(&extensions, TLSEXT_TYPE_key_share) ||
311 !CBB_add_u16(&extensions, 2 /* length */) ||
312 !CBB_add_u16(&extensions, group_id) ||
Steven Valdez5eead162016-11-11 22:23:25 -0500313 !ssl_complete_message(ssl, &cbb)) {
Steven Valdez5440fe02016-07-18 12:40:30 -0400314 CBB_cleanup(&cbb);
315 return ssl_hs_error;
316 }
317
318 hs->state = state_flush_hello_retry_request;
319 return ssl_hs_write_message;
320}
321
322static enum ssl_hs_wait_t do_flush_hello_retry_request(SSL *ssl,
323 SSL_HANDSHAKE *hs) {
324 hs->state = state_process_second_client_hello;
325 return ssl_hs_flush_and_read_message;
326}
327
328static enum ssl_hs_wait_t do_process_second_client_hello(SSL *ssl,
329 SSL_HANDSHAKE *hs) {
330 if (!tls13_check_message_type(ssl, SSL3_MT_CLIENT_HELLO)) {
331 return ssl_hs_error;
332 }
333
David Benjamine14ff062016-08-09 16:21:24 -0400334 struct ssl_early_callback_ctx client_hello;
335 if (!ssl_early_callback_init(ssl, &client_hello, ssl->init_msg,
David Benjamind7573dc2016-07-20 19:05:22 +0200336 ssl->init_num)) {
Steven Valdez5440fe02016-07-18 12:40:30 -0400337 OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_PARSE_FAILED);
338 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
339 return ssl_hs_error;
340 }
341
342 int need_retry;
David Benjamine14ff062016-08-09 16:21:24 -0400343 if (!resolve_ecdhe_secret(ssl, &need_retry, &client_hello)) {
Steven Valdez5440fe02016-07-18 12:40:30 -0400344 if (need_retry) {
345 /* Only send one HelloRetryRequest. */
346 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
347 OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CURVE);
Steven Valdez143e8b32016-07-11 13:19:03 -0400348 }
Steven Valdez5440fe02016-07-18 12:40:30 -0400349 return ssl_hs_error;
350 }
351
David Benjaminced94792016-11-14 17:12:11 +0900352 if (!ssl_hash_current_message(ssl)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400353 return ssl_hs_error;
354 }
355
David Benjamin613fe3b2016-07-22 17:39:29 +0200356 ssl->method->received_flight(ssl);
Steven Valdez143e8b32016-07-11 13:19:03 -0400357 hs->state = state_send_server_hello;
358 return ssl_hs_ok;
359}
360
361static enum ssl_hs_wait_t do_send_server_hello(SSL *ssl, SSL_HANDSHAKE *hs) {
362 CBB cbb, body, extensions;
363 if (!ssl->method->init_message(ssl, &cbb, &body, SSL3_MT_SERVER_HELLO) ||
364 !CBB_add_u16(&body, ssl->version) ||
365 !RAND_bytes(ssl->s3->server_random, sizeof(ssl->s3->server_random)) ||
366 !CBB_add_bytes(&body, ssl->s3->server_random, SSL3_RANDOM_SIZE) ||
367 !CBB_add_u16(&body, ssl_cipher_get_value(ssl->s3->tmp.new_cipher)) ||
368 !CBB_add_u16_length_prefixed(&body, &extensions) ||
Steven Valdez4aa154e2016-07-29 14:32:55 -0400369 !ssl_ext_pre_shared_key_add_serverhello(ssl, &extensions) ||
Steven Valdez803c77a2016-09-06 14:13:43 -0400370 !ssl_ext_key_share_add_serverhello(ssl, &extensions)) {
371 goto err;
372 }
373
374 if (!ssl->s3->session_reused) {
375 if (!CBB_add_u16(&extensions, TLSEXT_TYPE_signature_algorithms) ||
376 !CBB_add_u16(&extensions, 0)) {
377 goto err;
378 }
379 }
380
Steven Valdez5eead162016-11-11 22:23:25 -0500381 if (!ssl_complete_message(ssl, &cbb)) {
Steven Valdez803c77a2016-09-06 14:13:43 -0400382 goto err;
Steven Valdez143e8b32016-07-11 13:19:03 -0400383 }
384
385 hs->state = state_send_encrypted_extensions;
386 return ssl_hs_write_message;
Steven Valdez803c77a2016-09-06 14:13:43 -0400387
388err:
389 CBB_cleanup(&cbb);
390 return ssl_hs_error;
Steven Valdez143e8b32016-07-11 13:19:03 -0400391}
392
393static enum ssl_hs_wait_t do_send_encrypted_extensions(SSL *ssl,
394 SSL_HANDSHAKE *hs) {
395 if (!tls13_set_handshake_traffic(ssl)) {
396 return ssl_hs_error;
397 }
398
399 CBB cbb, body;
400 if (!ssl->method->init_message(ssl, &cbb, &body,
401 SSL3_MT_ENCRYPTED_EXTENSIONS) ||
402 !ssl_add_serverhello_tlsext(ssl, &body) ||
Steven Valdez5eead162016-11-11 22:23:25 -0500403 !ssl_complete_message(ssl, &cbb)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400404 CBB_cleanup(&cbb);
405 return ssl_hs_error;
406 }
407
408 hs->state = state_send_certificate_request;
409 return ssl_hs_write_message;
410}
411
412static enum ssl_hs_wait_t do_send_certificate_request(SSL *ssl,
413 SSL_HANDSHAKE *hs) {
414 /* Determine whether to request a client certificate. */
David Benjamina0486782016-10-06 19:11:32 -0400415 ssl->s3->hs->cert_request = !!(ssl->verify_mode & SSL_VERIFY_PEER);
Steven Valdez803c77a2016-09-06 14:13:43 -0400416 /* CertificateRequest may only be sent in non-resumption handshakes. */
417 if (ssl->s3->session_reused) {
David Benjamina0486782016-10-06 19:11:32 -0400418 ssl->s3->hs->cert_request = 0;
Steven Valdez143e8b32016-07-11 13:19:03 -0400419 }
420
David Benjamina0486782016-10-06 19:11:32 -0400421 if (!ssl->s3->hs->cert_request) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400422 /* Skip this state. */
423 hs->state = state_send_server_certificate;
424 return ssl_hs_ok;
425 }
426
427 CBB cbb, body, sigalgs_cbb;
428 if (!ssl->method->init_message(ssl, &cbb, &body,
429 SSL3_MT_CERTIFICATE_REQUEST) ||
430 !CBB_add_u8(&body, 0 /* no certificate_request_context. */)) {
431 goto err;
432 }
433
434 const uint16_t *sigalgs;
David Benjamin3ef76972016-10-17 17:59:54 -0400435 size_t num_sigalgs = tls12_get_verify_sigalgs(ssl, &sigalgs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400436 if (!CBB_add_u16_length_prefixed(&body, &sigalgs_cbb)) {
437 goto err;
438 }
439
David Benjamin0fc37ef2016-08-17 15:29:46 -0400440 for (size_t i = 0; i < num_sigalgs; i++) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400441 if (!CBB_add_u16(&sigalgs_cbb, sigalgs[i])) {
442 goto err;
443 }
444 }
445
446 if (!ssl_add_client_CA_list(ssl, &body) ||
447 !CBB_add_u16(&body, 0 /* empty certificate_extensions. */) ||
Steven Valdez5eead162016-11-11 22:23:25 -0500448 !ssl_complete_message(ssl, &cbb)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400449 goto err;
450 }
451
452 hs->state = state_send_server_certificate;
453 return ssl_hs_write_message;
454
455err:
456 CBB_cleanup(&cbb);
457 return ssl_hs_error;
458}
459
460static enum ssl_hs_wait_t do_send_server_certificate(SSL *ssl,
461 SSL_HANDSHAKE *hs) {
Steven Valdez803c77a2016-09-06 14:13:43 -0400462 if (ssl->s3->session_reused) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400463 hs->state = state_send_server_finished;
464 return ssl_hs_ok;
465 }
466
467 if (!ssl_has_certificate(ssl)) {
468 OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATE_SET);
469 return ssl_hs_error;
470 }
471
472 if (!tls13_prepare_certificate(ssl)) {
473 return ssl_hs_error;
474 }
475
476 hs->state = state_send_server_certificate_verify;
477 return ssl_hs_write_message;
478}
479
480static enum ssl_hs_wait_t do_send_server_certificate_verify(SSL *ssl,
481 SSL_HANDSHAKE *hs,
482 int is_first_run) {
483 switch (tls13_prepare_certificate_verify(ssl, is_first_run)) {
484 case ssl_private_key_success:
485 hs->state = state_send_server_finished;
486 return ssl_hs_write_message;
487
488 case ssl_private_key_retry:
489 hs->state = state_complete_server_certificate_verify;
490 return ssl_hs_private_key_operation;
491
492 case ssl_private_key_failure:
493 return ssl_hs_error;
494 }
495
496 assert(0);
497 return ssl_hs_error;
498}
499
500static enum ssl_hs_wait_t do_send_server_finished(SSL *ssl, SSL_HANDSHAKE *hs) {
501 if (!tls13_prepare_finished(ssl)) {
502 return ssl_hs_error;
503 }
504
505 hs->state = state_flush;
506 return ssl_hs_write_message;
507}
508
509static enum ssl_hs_wait_t do_flush(SSL *ssl, SSL_HANDSHAKE *hs) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400510 /* Update the secret to the master secret and derive traffic keys. */
Steven Valdez143e8b32016-07-11 13:19:03 -0400511 if (!tls13_advance_key_schedule(ssl, kZeroes, hs->hash_len) ||
512 !tls13_derive_traffic_secret_0(ssl) ||
513 !tls13_set_traffic_key(ssl, type_data, evp_aead_seal,
Steven Valdezc4aa7272016-10-03 12:25:56 -0400514 hs->server_traffic_secret_0, hs->hash_len)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400515 return ssl_hs_error;
516 }
517
518 hs->state = state_process_client_certificate;
David Benjaminf2401eb2016-07-18 22:25:05 +0200519 return ssl_hs_flush_and_read_message;
Steven Valdez143e8b32016-07-11 13:19:03 -0400520}
521
522static enum ssl_hs_wait_t do_process_client_certificate(SSL *ssl,
523 SSL_HANDSHAKE *hs) {
David Benjamina0486782016-10-06 19:11:32 -0400524 if (!ssl->s3->hs->cert_request) {
Adam Langley37646832016-08-01 16:16:46 -0700525 /* OpenSSL returns X509_V_OK when no certificates are requested. This is
David Benjamindd634eb2016-08-18 16:40:28 -0400526 * classed by them as a bug, but it's assumed by at least NGINX. */
Adam Langley37646832016-08-01 16:16:46 -0700527 ssl->s3->new_session->verify_result = X509_V_OK;
528
Steven Valdez143e8b32016-07-11 13:19:03 -0400529 /* Skip this state. */
Nick Harper60a85cb2016-09-23 16:25:11 -0700530 hs->state = state_process_channel_id;
Steven Valdez143e8b32016-07-11 13:19:03 -0400531 return ssl_hs_ok;
532 }
533
David Benjamin4087df92016-08-01 20:16:31 -0400534 const int allow_anonymous =
535 (ssl->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) == 0;
536
Steven Valdez143e8b32016-07-11 13:19:03 -0400537 if (!tls13_check_message_type(ssl, SSL3_MT_CERTIFICATE) ||
David Benjamin4087df92016-08-01 20:16:31 -0400538 !tls13_process_certificate(ssl, allow_anonymous) ||
David Benjaminced94792016-11-14 17:12:11 +0900539 !ssl_hash_current_message(ssl)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400540 return ssl_hs_error;
541 }
542
David Benjamin3ce43892016-08-01 19:41:34 -0400543 /* For historical reasons, the server's copy of the chain does not include the
544 * leaf while the client's does. */
Adam Langleyc5ac2b62016-11-07 12:02:35 -0800545 if (sk_X509_num(ssl->s3->new_session->x509_chain) > 0) {
546 X509_free(sk_X509_shift(ssl->s3->new_session->x509_chain));
David Benjamin3ce43892016-08-01 19:41:34 -0400547 }
548
Steven Valdez143e8b32016-07-11 13:19:03 -0400549 hs->state = state_process_client_certificate_verify;
550 return ssl_hs_read_message;
551}
552
553static enum ssl_hs_wait_t do_process_client_certificate_verify(
554 SSL *ssl, SSL_HANDSHAKE *hs) {
Adam Langleyc5ac2b62016-11-07 12:02:35 -0800555 if (ssl->s3->new_session->x509_peer == NULL) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400556 /* Skip this state. */
Nick Harper60a85cb2016-09-23 16:25:11 -0700557 hs->state = state_process_channel_id;
Steven Valdez143e8b32016-07-11 13:19:03 -0400558 return ssl_hs_ok;
559 }
560
561 if (!tls13_check_message_type(ssl, SSL3_MT_CERTIFICATE_VERIFY) ||
562 !tls13_process_certificate_verify(ssl) ||
David Benjaminced94792016-11-14 17:12:11 +0900563 !ssl_hash_current_message(ssl)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400564 return 0;
565 }
566
Nick Harper60a85cb2016-09-23 16:25:11 -0700567 hs->state = state_process_channel_id;
568 return ssl_hs_read_message;
569}
570
571static enum ssl_hs_wait_t do_process_channel_id(SSL *ssl, SSL_HANDSHAKE *hs) {
572 if (!ssl->s3->tlsext_channel_id_valid) {
573 hs->state = state_process_client_finished;
574 return ssl_hs_ok;
575 }
576
577 if (!tls13_check_message_type(ssl, SSL3_MT_CHANNEL_ID) ||
578 !tls1_verify_channel_id(ssl) ||
David Benjaminced94792016-11-14 17:12:11 +0900579 !ssl_hash_current_message(ssl)) {
Nick Harper60a85cb2016-09-23 16:25:11 -0700580 return ssl_hs_error;
581 }
582
Steven Valdez143e8b32016-07-11 13:19:03 -0400583 hs->state = state_process_client_finished;
584 return ssl_hs_read_message;
585}
586
587static enum ssl_hs_wait_t do_process_client_finished(SSL *ssl,
588 SSL_HANDSHAKE *hs) {
589 if (!tls13_check_message_type(ssl, SSL3_MT_FINISHED) ||
590 !tls13_process_finished(ssl) ||
David Benjaminced94792016-11-14 17:12:11 +0900591 !ssl_hash_current_message(ssl) ||
Steven Valdez143e8b32016-07-11 13:19:03 -0400592 /* evp_aead_seal keys have already been switched. */
593 !tls13_set_traffic_key(ssl, type_data, evp_aead_open,
Steven Valdezc4aa7272016-10-03 12:25:56 -0400594 hs->client_traffic_secret_0, hs->hash_len) ||
Steven Valdez143e8b32016-07-11 13:19:03 -0400595 !tls13_finalize_keys(ssl)) {
596 return ssl_hs_error;
597 }
598
David Benjamin613fe3b2016-07-22 17:39:29 +0200599 ssl->method->received_flight(ssl);
David Benjamin123db572016-11-03 16:59:25 -0400600
601 /* Refresh the session timestamp so that it is measured from ticket
602 * issuance. */
603 ssl_session_refresh_time(ssl, ssl->s3->new_session);
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400604 hs->state = state_send_new_session_ticket;
Steven Valdez143e8b32016-07-11 13:19:03 -0400605 return ssl_hs_ok;
606}
607
David Benjamin0a011fc2016-11-03 17:19:16 -0400608/* TLS 1.3 recommends single-use tickets, so issue multiple tickets in case the
609 * client makes several connections before getting a renewal. */
610static const int kNumTickets = 2;
611
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400612static enum ssl_hs_wait_t do_send_new_session_ticket(SSL *ssl,
613 SSL_HANDSHAKE *hs) {
614 SSL_SESSION *session = ssl->s3->new_session;
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400615
Steven Valdez5b986082016-09-01 12:29:49 -0400616 /* TODO(svaldez): Add support for sending 0RTT through TicketEarlyDataInfo
617 * extension. */
618
David Benjamin1a5e8ec2016-10-07 15:19:18 -0400619 CBB cbb, body, ke_modes, auth_modes, ticket, extensions;
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400620 if (!ssl->method->init_message(ssl, &cbb, &body,
621 SSL3_MT_NEW_SESSION_TICKET) ||
David Benjamin123db572016-11-03 16:59:25 -0400622 !CBB_add_u32(&body, session->timeout) ||
Steven Valdez5b986082016-09-01 12:29:49 -0400623 !CBB_add_u8_length_prefixed(&body, &ke_modes) ||
624 !CBB_add_u8(&ke_modes, SSL_PSK_DHE_KE) ||
625 !CBB_add_u8_length_prefixed(&body, &auth_modes) ||
626 !CBB_add_u8(&auth_modes, SSL_PSK_AUTH) ||
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400627 !CBB_add_u16_length_prefixed(&body, &ticket) ||
628 !ssl_encrypt_ticket(ssl, &ticket, session) ||
David Benjamin1a5e8ec2016-10-07 15:19:18 -0400629 !CBB_add_u16_length_prefixed(&body, &extensions)) {
630 goto err;
631 }
632
633 /* Add a fake extension. See draft-davidben-tls-grease-01. */
David Benjamin079b3942016-10-20 13:19:20 -0400634 if (!CBB_add_u16(&extensions,
635 ssl_get_grease_value(ssl, ssl_grease_ticket_extension)) ||
636 !CBB_add_u16(&extensions, 0 /* empty */)) {
637 goto err;
David Benjamin1a5e8ec2016-10-07 15:19:18 -0400638 }
639
Steven Valdez5eead162016-11-11 22:23:25 -0500640 if (!ssl_complete_message(ssl, &cbb)) {
David Benjamin1a5e8ec2016-10-07 15:19:18 -0400641 goto err;
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400642 }
643
644 hs->session_tickets_sent++;
David Benjamin0a011fc2016-11-03 17:19:16 -0400645 if (hs->session_tickets_sent >= kNumTickets) {
646 hs->state = state_flush_new_session_tickets;
647 } else {
648 hs->state = state_send_new_session_ticket;
649 }
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400650
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400651 return ssl_hs_write_message;
David Benjamin1a5e8ec2016-10-07 15:19:18 -0400652
653err:
654 CBB_cleanup(&cbb);
655 return ssl_hs_error;
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400656}
657
David Benjamin0a011fc2016-11-03 17:19:16 -0400658static enum ssl_hs_wait_t do_flush_new_session_tickets(SSL *ssl,
659 SSL_HANDSHAKE *hs) {
660 hs->state = state_done;
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400661 return ssl_hs_flush;
662}
663
Steven Valdez143e8b32016-07-11 13:19:03 -0400664enum ssl_hs_wait_t tls13_server_handshake(SSL *ssl) {
665 SSL_HANDSHAKE *hs = ssl->s3->hs;
666
667 while (hs->state != state_done) {
668 enum ssl_hs_wait_t ret = ssl_hs_error;
669 enum server_hs_state_t state = hs->state;
670 switch (state) {
671 case state_process_client_hello:
672 ret = do_process_client_hello(ssl, hs);
673 break;
David Benjamin25fe85b2016-08-09 20:00:32 -0400674 case state_select_parameters:
675 ret = do_select_parameters(ssl, hs);
676 break;
Steven Valdez5440fe02016-07-18 12:40:30 -0400677 case state_send_hello_retry_request:
678 ret = do_send_hello_retry_request(ssl, hs);
679 break;
680 case state_flush_hello_retry_request:
681 ret = do_flush_hello_retry_request(ssl, hs);
682 break;
683 case state_process_second_client_hello:
684 ret = do_process_second_client_hello(ssl, hs);
685 break;
Steven Valdez143e8b32016-07-11 13:19:03 -0400686 case state_send_server_hello:
687 ret = do_send_server_hello(ssl, hs);
688 break;
689 case state_send_encrypted_extensions:
690 ret = do_send_encrypted_extensions(ssl, hs);
691 break;
692 case state_send_certificate_request:
693 ret = do_send_certificate_request(ssl, hs);
694 break;
695 case state_send_server_certificate:
696 ret = do_send_server_certificate(ssl, hs);
697 break;
698 case state_send_server_certificate_verify:
699 ret = do_send_server_certificate_verify(ssl, hs, 1 /* first run */);
700 break;
701 case state_complete_server_certificate_verify:
702 ret = do_send_server_certificate_verify(ssl, hs, 0 /* complete */);
703 break;
704 case state_send_server_finished:
705 ret = do_send_server_finished(ssl, hs);
706 break;
707 case state_flush:
708 ret = do_flush(ssl, hs);
709 break;
Steven Valdez143e8b32016-07-11 13:19:03 -0400710 case state_process_client_certificate:
711 ret = do_process_client_certificate(ssl, hs);
712 break;
713 case state_process_client_certificate_verify:
714 ret = do_process_client_certificate_verify(ssl, hs);
715 break;
Nick Harper60a85cb2016-09-23 16:25:11 -0700716 case state_process_channel_id:
717 ret = do_process_channel_id(ssl, hs);
718 break;
Steven Valdez143e8b32016-07-11 13:19:03 -0400719 case state_process_client_finished:
720 ret = do_process_client_finished(ssl, hs);
721 break;
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400722 case state_send_new_session_ticket:
723 ret = do_send_new_session_ticket(ssl, hs);
724 break;
David Benjamin0a011fc2016-11-03 17:19:16 -0400725 case state_flush_new_session_tickets:
726 ret = do_flush_new_session_tickets(ssl, hs);
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400727 break;
Steven Valdez143e8b32016-07-11 13:19:03 -0400728 case state_done:
729 ret = ssl_hs_ok;
730 break;
731 }
732
733 if (ret != ssl_hs_ok) {
734 return ret;
735 }
736 }
737
738 return ssl_hs_ok;
739}