blob: eaeab065c59bddfe445fadc629f425c0b38e34ab [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
David Benjaminc3c88822016-11-14 10:32:04 +090090static enum ssl_hs_wait_t do_process_client_hello(SSL_HANDSHAKE *hs) {
91 SSL *const ssl = hs->ssl;
Steven Valdez143e8b32016-07-11 13:19:03 -040092 if (!tls13_check_message_type(ssl, SSL3_MT_CLIENT_HELLO)) {
93 return ssl_hs_error;
94 }
95
David Benjamine14ff062016-08-09 16:21:24 -040096 struct ssl_early_callback_ctx client_hello;
97 if (!ssl_early_callback_init(ssl, &client_hello, ssl->init_msg,
David Benjamind7573dc2016-07-20 19:05:22 +020098 ssl->init_num)) {
Steven Valdez143e8b32016-07-11 13:19:03 -040099 OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_PARSE_FAILED);
100 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
101 return ssl_hs_error;
102 }
103
Steven Valdez143e8b32016-07-11 13:19:03 -0400104 assert(ssl->s3->have_version);
105
106 /* Load the client random. */
David Benjamine14ff062016-08-09 16:21:24 -0400107 if (client_hello.random_len != SSL3_RANDOM_SIZE) {
108 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
David Benjamin6929f272016-11-16 19:10:08 +0900109 return ssl_hs_error;
David Benjamine14ff062016-08-09 16:21:24 -0400110 }
111 memcpy(ssl->s3->client_random, client_hello.random, client_hello.random_len);
Steven Valdez143e8b32016-07-11 13:19:03 -0400112
David Benjamin4eb95cc2016-11-16 17:08:23 +0900113 /* TLS 1.3 requires the peer only advertise the null compression. */
114 if (client_hello.compression_methods_len != 1 ||
115 client_hello.compression_methods[0] != 0) {
116 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_COMPRESSION_LIST);
117 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
David Benjamin6929f272016-11-16 19:10:08 +0900118 return ssl_hs_error;
Steven Valdez4aa154e2016-07-29 14:32:55 -0400119 }
120
David Benjamin4eb95cc2016-11-16 17:08:23 +0900121 /* TLS extensions. */
122 if (!ssl_parse_clienthello_tlsext(ssl, &client_hello)) {
123 OPENSSL_PUT_ERROR(SSL, SSL_R_PARSE_TLSEXT);
124 return ssl_hs_error;
125 }
Steven Valdeza833c352016-11-01 13:39:36 -0400126
David Benjamin34202b92016-11-16 19:07:53 +0900127 hs->state = state_select_parameters;
128 return ssl_hs_ok;
129}
130
131static const SSL_CIPHER *choose_tls13_cipher(
132 const SSL *ssl, const struct ssl_early_callback_ctx *client_hello) {
133 if (client_hello->cipher_suites_len % 2 != 0) {
134 return NULL;
135 }
136
137 CBS cipher_suites;
138 CBS_init(&cipher_suites, client_hello->cipher_suites,
139 client_hello->cipher_suites_len);
140
141 const int aes_is_fine = EVP_has_aes_hardware();
David Benjaminf01f42a2016-11-16 19:05:33 +0900142 const uint16_t version = ssl3_protocol_version(ssl);
David Benjamin34202b92016-11-16 19:07:53 +0900143
144 const SSL_CIPHER *best = NULL;
145 while (CBS_len(&cipher_suites) > 0) {
146 uint16_t cipher_suite;
147 if (!CBS_get_u16(&cipher_suites, &cipher_suite)) {
148 return NULL;
149 }
150
David Benjaminf01f42a2016-11-16 19:05:33 +0900151 /* Limit to TLS 1.3 ciphers we know about. */
David Benjamin34202b92016-11-16 19:07:53 +0900152 const SSL_CIPHER *candidate = SSL_get_cipher_by_value(cipher_suite);
David Benjaminf01f42a2016-11-16 19:05:33 +0900153 if (candidate == NULL ||
154 SSL_CIPHER_get_min_version(candidate) > version ||
155 SSL_CIPHER_get_max_version(candidate) < version) {
David Benjamin34202b92016-11-16 19:07:53 +0900156 continue;
157 }
158
159 /* TLS 1.3 removes legacy ciphers, so honor the client order, but prefer
160 * ChaCha20 if we do not have AES hardware. */
161 if (aes_is_fine) {
162 return candidate;
163 }
164
165 if (candidate->algorithm_enc == SSL_CHACHA20POLY1305) {
166 return candidate;
167 }
168
169 if (best == NULL) {
170 best = candidate;
171 }
172 }
173
174 return best;
175}
176
David Benjaminc3c88822016-11-14 10:32:04 +0900177static enum ssl_hs_wait_t do_select_parameters(SSL_HANDSHAKE *hs) {
178 SSL *const ssl = hs->ssl;
David Benjamin34202b92016-11-16 19:07:53 +0900179 /* Call |cert_cb| to update server certificates if required. */
180 if (ssl->cert->cert_cb != NULL) {
181 int rv = ssl->cert->cert_cb(ssl, ssl->cert->cert_cb_arg);
182 if (rv == 0) {
183 OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_CB_ERROR);
184 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
185 return ssl_hs_error;
186 }
187 if (rv < 0) {
188 hs->state = state_select_parameters;
189 return ssl_hs_x509_lookup;
190 }
191 }
192
193 struct ssl_early_callback_ctx client_hello;
194 if (!ssl_early_callback_init(ssl, &client_hello, ssl->init_msg,
195 ssl->init_num)) {
196 OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_PARSE_FAILED);
197 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
198 return ssl_hs_error;
199 }
200
David Benjaminf01f42a2016-11-16 19:05:33 +0900201 /* Negotiate the cipher suite. */
202 ssl->s3->tmp.new_cipher = choose_tls13_cipher(ssl, &client_hello);
203 if (ssl->s3->tmp.new_cipher == NULL) {
204 OPENSSL_PUT_ERROR(SSL, SSL_R_NO_SHARED_CIPHER);
205 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
206 return ssl_hs_error;
207 }
208
209 /* Decode the ticket if we agree on a PSK key exchange mode. */
David Benjamin4eb95cc2016-11-16 17:08:23 +0900210 uint8_t alert = SSL_AD_DECODE_ERROR;
211 SSL_SESSION *session = NULL;
212 CBS pre_shared_key, binders;
213 if (hs->accept_psk_mode &&
214 ssl_early_callback_get_extension(&client_hello, &pre_shared_key,
215 TLSEXT_TYPE_pre_shared_key)) {
216 /* Verify that the pre_shared_key extension is the last extension in
217 * ClientHello. */
218 if (CBS_data(&pre_shared_key) + CBS_len(&pre_shared_key) !=
219 client_hello.extensions + client_hello.extensions_len) {
220 OPENSSL_PUT_ERROR(SSL, SSL_R_PRE_SHARED_KEY_MUST_BE_LAST);
221 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
222 return ssl_hs_error;
223 }
224
225 if (!ssl_ext_pre_shared_key_parse_clienthello(ssl, &session, &binders,
226 &alert, &pre_shared_key)) {
227 ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
228 return ssl_hs_error;
Steven Valdeza833c352016-11-01 13:39:36 -0400229 }
230 }
231
Steven Valdez4aa154e2016-07-29 14:32:55 -0400232 if (session != NULL &&
David Benjamin75f99142016-11-12 12:36:06 +0900233 !ssl_session_is_resumable(ssl, session)) {
Steven Valdez4aa154e2016-07-29 14:32:55 -0400234 SSL_SESSION_free(session);
235 session = NULL;
236 }
237
David Benjaminf01f42a2016-11-16 19:05:33 +0900238 /* Set up the new session, either using the original one as a template or
239 * creating a fresh one. */
Steven Valdez4aa154e2016-07-29 14:32:55 -0400240 if (session == NULL) {
241 if (!ssl_get_new_session(ssl, 1 /* server */)) {
242 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
243 return ssl_hs_error;
244 }
David Benjaminf01f42a2016-11-16 19:05:33 +0900245
246 ssl->s3->new_session->cipher = ssl->s3->tmp.new_cipher;
247
248 /* On new sessions, stash the SNI value in the session. */
249 if (ssl->s3->hs->hostname != NULL) {
250 ssl->s3->new_session->tlsext_hostname = BUF_strdup(ssl->s3->hs->hostname);
251 if (ssl->s3->new_session->tlsext_hostname == NULL) {
252 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
253 return ssl_hs_error;
254 }
255 }
Steven Valdez4aa154e2016-07-29 14:32:55 -0400256 } else {
Steven Valdeza833c352016-11-01 13:39:36 -0400257 /* Check the PSK binder. */
258 if (!tls13_verify_psk_binder(ssl, session, &binders)) {
259 SSL_SESSION_free(session);
260 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR);
261 return ssl_hs_error;
262 }
263
Steven Valdez4aa154e2016-07-29 14:32:55 -0400264 /* Only authentication information carries over in TLS 1.3. */
265 ssl->s3->new_session = SSL_SESSION_dup(session, SSL_SESSION_DUP_AUTH_ONLY);
266 if (ssl->s3->new_session == NULL) {
267 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
268 return ssl_hs_error;
269 }
270 ssl->s3->session_reused = 1;
Steven Valdez4aa154e2016-07-29 14:32:55 -0400271 SSL_SESSION_free(session);
Steven Valdez143e8b32016-07-11 13:19:03 -0400272 }
273
274 if (ssl->ctx->dos_protection_cb != NULL &&
David Benjamine14ff062016-08-09 16:21:24 -0400275 ssl->ctx->dos_protection_cb(&client_hello) == 0) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400276 /* Connection rejected for DOS reasons. */
277 OPENSSL_PUT_ERROR(SSL, SSL_R_CONNECTION_REJECTED);
David Benjamin2c66e072016-09-16 15:58:00 -0400278 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
Steven Valdez143e8b32016-07-11 13:19:03 -0400279 return ssl_hs_error;
280 }
281
David Benjaminf01f42a2016-11-16 19:05:33 +0900282 /* HTTP/2 negotiation depends on the cipher suite, so ALPN negotiation was
283 * deferred. Complete it now. */
David Benjamin9ef31f02016-10-31 18:01:13 -0400284 if (!ssl_negotiate_alpn(ssl, &alert, &client_hello)) {
285 ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
286 return ssl_hs_error;
287 }
Steven Valdez803c77a2016-09-06 14:13:43 -0400288
David Benjamin8f820b42016-11-30 11:24:40 -0500289 /* The PRF hash is now known. Set up the key schedule. */
Steven Valdez803c77a2016-09-06 14:13:43 -0400290 size_t hash_len =
Steven Valdez143e8b32016-07-11 13:19:03 -0400291 EVP_MD_size(ssl_get_handshake_digest(ssl_get_algorithm_prf(ssl)));
David Benjamin8f820b42016-11-30 11:24:40 -0500292 if (!tls13_init_key_schedule(ssl)) {
293 return ssl_hs_error;
Steven Valdez143e8b32016-07-11 13:19:03 -0400294 }
295
David Benjamin8f820b42016-11-30 11:24:40 -0500296 /* Incorporate the PSK into the running secret. */
297 if (ssl->s3->session_reused) {
298 if (!tls13_advance_key_schedule(ssl, ssl->s3->new_session->master_key,
299 ssl->s3->new_session->master_key_length)) {
300 return ssl_hs_error;
301 }
302 } else if (!tls13_advance_key_schedule(ssl, kZeroes, hash_len)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400303 return ssl_hs_error;
304 }
305
David Benjaminf01f42a2016-11-16 19:05:33 +0900306 ssl->method->received_flight(ssl);
307
Steven Valdez143e8b32016-07-11 13:19:03 -0400308 /* Resolve ECDHE and incorporate it into the secret. */
Steven Valdez5440fe02016-07-18 12:40:30 -0400309 int need_retry;
David Benjamine14ff062016-08-09 16:21:24 -0400310 if (!resolve_ecdhe_secret(ssl, &need_retry, &client_hello)) {
Steven Valdez5440fe02016-07-18 12:40:30 -0400311 if (need_retry) {
312 hs->state = state_send_hello_retry_request;
313 return ssl_hs_ok;
Steven Valdez143e8b32016-07-11 13:19:03 -0400314 }
Steven Valdez5440fe02016-07-18 12:40:30 -0400315 return ssl_hs_error;
316 }
Steven Valdez143e8b32016-07-11 13:19:03 -0400317
Steven Valdez5440fe02016-07-18 12:40:30 -0400318 hs->state = state_send_server_hello;
319 return ssl_hs_ok;
320}
Steven Valdez143e8b32016-07-11 13:19:03 -0400321
David Benjaminc3c88822016-11-14 10:32:04 +0900322static enum ssl_hs_wait_t do_send_hello_retry_request(SSL_HANDSHAKE *hs) {
323 SSL *const ssl = hs->ssl;
Steven Valdez5440fe02016-07-18 12:40:30 -0400324 CBB cbb, body, extensions;
325 uint16_t group_id;
326 if (!ssl->method->init_message(ssl, &cbb, &body,
327 SSL3_MT_HELLO_RETRY_REQUEST) ||
328 !CBB_add_u16(&body, ssl->version) ||
Steven Valdez5440fe02016-07-18 12:40:30 -0400329 !tls1_get_shared_group(ssl, &group_id) ||
Steven Valdez5440fe02016-07-18 12:40:30 -0400330 !CBB_add_u16_length_prefixed(&body, &extensions) ||
David Benjamin3baa6e12016-10-07 21:10:38 -0400331 !CBB_add_u16(&extensions, TLSEXT_TYPE_key_share) ||
332 !CBB_add_u16(&extensions, 2 /* length */) ||
333 !CBB_add_u16(&extensions, group_id) ||
Steven Valdez5eead162016-11-11 22:23:25 -0500334 !ssl_complete_message(ssl, &cbb)) {
Steven Valdez5440fe02016-07-18 12:40:30 -0400335 CBB_cleanup(&cbb);
336 return ssl_hs_error;
337 }
338
339 hs->state = state_flush_hello_retry_request;
340 return ssl_hs_write_message;
341}
342
David Benjaminc3c88822016-11-14 10:32:04 +0900343static enum ssl_hs_wait_t do_flush_hello_retry_request(SSL_HANDSHAKE *hs) {
Steven Valdez5440fe02016-07-18 12:40:30 -0400344 hs->state = state_process_second_client_hello;
345 return ssl_hs_flush_and_read_message;
346}
347
David Benjaminc3c88822016-11-14 10:32:04 +0900348static enum ssl_hs_wait_t do_process_second_client_hello(SSL_HANDSHAKE *hs) {
349 SSL *const ssl = hs->ssl;
Steven Valdez5440fe02016-07-18 12:40:30 -0400350 if (!tls13_check_message_type(ssl, SSL3_MT_CLIENT_HELLO)) {
351 return ssl_hs_error;
352 }
353
David Benjamine14ff062016-08-09 16:21:24 -0400354 struct ssl_early_callback_ctx client_hello;
355 if (!ssl_early_callback_init(ssl, &client_hello, ssl->init_msg,
David Benjamind7573dc2016-07-20 19:05:22 +0200356 ssl->init_num)) {
Steven Valdez5440fe02016-07-18 12:40:30 -0400357 OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_PARSE_FAILED);
358 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
359 return ssl_hs_error;
360 }
361
362 int need_retry;
David Benjamine14ff062016-08-09 16:21:24 -0400363 if (!resolve_ecdhe_secret(ssl, &need_retry, &client_hello)) {
Steven Valdez5440fe02016-07-18 12:40:30 -0400364 if (need_retry) {
365 /* Only send one HelloRetryRequest. */
366 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
367 OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CURVE);
Steven Valdez143e8b32016-07-11 13:19:03 -0400368 }
Steven Valdez5440fe02016-07-18 12:40:30 -0400369 return ssl_hs_error;
370 }
371
David Benjaminced94792016-11-14 17:12:11 +0900372 if (!ssl_hash_current_message(ssl)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400373 return ssl_hs_error;
374 }
375
David Benjamin613fe3b2016-07-22 17:39:29 +0200376 ssl->method->received_flight(ssl);
Steven Valdez143e8b32016-07-11 13:19:03 -0400377 hs->state = state_send_server_hello;
378 return ssl_hs_ok;
379}
380
David Benjaminc3c88822016-11-14 10:32:04 +0900381static enum ssl_hs_wait_t do_send_server_hello(SSL_HANDSHAKE *hs) {
382 SSL *const ssl = hs->ssl;
Steven Valdez143e8b32016-07-11 13:19:03 -0400383 CBB cbb, body, extensions;
384 if (!ssl->method->init_message(ssl, &cbb, &body, SSL3_MT_SERVER_HELLO) ||
385 !CBB_add_u16(&body, ssl->version) ||
386 !RAND_bytes(ssl->s3->server_random, sizeof(ssl->s3->server_random)) ||
387 !CBB_add_bytes(&body, ssl->s3->server_random, SSL3_RANDOM_SIZE) ||
388 !CBB_add_u16(&body, ssl_cipher_get_value(ssl->s3->tmp.new_cipher)) ||
389 !CBB_add_u16_length_prefixed(&body, &extensions) ||
Steven Valdez4aa154e2016-07-29 14:32:55 -0400390 !ssl_ext_pre_shared_key_add_serverhello(ssl, &extensions) ||
Steven Valdeza833c352016-11-01 13:39:36 -0400391 !ssl_ext_key_share_add_serverhello(ssl, &extensions) ||
392 !ssl_complete_message(ssl, &cbb)) {
Steven Valdez803c77a2016-09-06 14:13:43 -0400393 goto err;
Steven Valdez143e8b32016-07-11 13:19:03 -0400394 }
395
396 hs->state = state_send_encrypted_extensions;
397 return ssl_hs_write_message;
Steven Valdez803c77a2016-09-06 14:13:43 -0400398
399err:
400 CBB_cleanup(&cbb);
401 return ssl_hs_error;
Steven Valdez143e8b32016-07-11 13:19:03 -0400402}
403
David Benjaminc3c88822016-11-14 10:32:04 +0900404static enum ssl_hs_wait_t do_send_encrypted_extensions(SSL_HANDSHAKE *hs) {
405 SSL *const ssl = hs->ssl;
Steven Valdez143e8b32016-07-11 13:19:03 -0400406 if (!tls13_set_handshake_traffic(ssl)) {
407 return ssl_hs_error;
408 }
409
410 CBB cbb, body;
411 if (!ssl->method->init_message(ssl, &cbb, &body,
412 SSL3_MT_ENCRYPTED_EXTENSIONS) ||
413 !ssl_add_serverhello_tlsext(ssl, &body) ||
Steven Valdez5eead162016-11-11 22:23:25 -0500414 !ssl_complete_message(ssl, &cbb)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400415 CBB_cleanup(&cbb);
416 return ssl_hs_error;
417 }
418
419 hs->state = state_send_certificate_request;
420 return ssl_hs_write_message;
421}
422
David Benjaminc3c88822016-11-14 10:32:04 +0900423static enum ssl_hs_wait_t do_send_certificate_request(SSL_HANDSHAKE *hs) {
424 SSL *const ssl = hs->ssl;
Steven Valdez143e8b32016-07-11 13:19:03 -0400425 /* Determine whether to request a client certificate. */
David Benjaminc3c88822016-11-14 10:32:04 +0900426 hs->cert_request = !!(ssl->verify_mode & SSL_VERIFY_PEER);
Steven Valdez803c77a2016-09-06 14:13:43 -0400427 /* CertificateRequest may only be sent in non-resumption handshakes. */
428 if (ssl->s3->session_reused) {
David Benjaminc3c88822016-11-14 10:32:04 +0900429 hs->cert_request = 0;
Steven Valdez143e8b32016-07-11 13:19:03 -0400430 }
431
David Benjaminc3c88822016-11-14 10:32:04 +0900432 if (!hs->cert_request) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400433 /* Skip this state. */
434 hs->state = state_send_server_certificate;
435 return ssl_hs_ok;
436 }
437
438 CBB cbb, body, sigalgs_cbb;
439 if (!ssl->method->init_message(ssl, &cbb, &body,
440 SSL3_MT_CERTIFICATE_REQUEST) ||
441 !CBB_add_u8(&body, 0 /* no certificate_request_context. */)) {
442 goto err;
443 }
444
445 const uint16_t *sigalgs;
David Benjamin3ef76972016-10-17 17:59:54 -0400446 size_t num_sigalgs = tls12_get_verify_sigalgs(ssl, &sigalgs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400447 if (!CBB_add_u16_length_prefixed(&body, &sigalgs_cbb)) {
448 goto err;
449 }
450
David Benjamin0fc37ef2016-08-17 15:29:46 -0400451 for (size_t i = 0; i < num_sigalgs; i++) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400452 if (!CBB_add_u16(&sigalgs_cbb, sigalgs[i])) {
453 goto err;
454 }
455 }
456
457 if (!ssl_add_client_CA_list(ssl, &body) ||
458 !CBB_add_u16(&body, 0 /* empty certificate_extensions. */) ||
Steven Valdez5eead162016-11-11 22:23:25 -0500459 !ssl_complete_message(ssl, &cbb)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400460 goto err;
461 }
462
463 hs->state = state_send_server_certificate;
464 return ssl_hs_write_message;
465
466err:
467 CBB_cleanup(&cbb);
468 return ssl_hs_error;
469}
470
David Benjaminc3c88822016-11-14 10:32:04 +0900471static enum ssl_hs_wait_t do_send_server_certificate(SSL_HANDSHAKE *hs) {
472 SSL *const ssl = hs->ssl;
Steven Valdez803c77a2016-09-06 14:13:43 -0400473 if (ssl->s3->session_reused) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400474 hs->state = state_send_server_finished;
475 return ssl_hs_ok;
476 }
477
478 if (!ssl_has_certificate(ssl)) {
479 OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATE_SET);
480 return ssl_hs_error;
481 }
482
483 if (!tls13_prepare_certificate(ssl)) {
484 return ssl_hs_error;
485 }
486
487 hs->state = state_send_server_certificate_verify;
488 return ssl_hs_write_message;
489}
490
David Benjaminc3c88822016-11-14 10:32:04 +0900491static enum ssl_hs_wait_t do_send_server_certificate_verify(SSL_HANDSHAKE *hs,
Steven Valdez143e8b32016-07-11 13:19:03 -0400492 int is_first_run) {
David Benjaminc3c88822016-11-14 10:32:04 +0900493 switch (tls13_prepare_certificate_verify(hs->ssl, is_first_run)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400494 case ssl_private_key_success:
495 hs->state = state_send_server_finished;
496 return ssl_hs_write_message;
497
498 case ssl_private_key_retry:
499 hs->state = state_complete_server_certificate_verify;
500 return ssl_hs_private_key_operation;
501
502 case ssl_private_key_failure:
503 return ssl_hs_error;
504 }
505
506 assert(0);
507 return ssl_hs_error;
508}
509
David Benjaminc3c88822016-11-14 10:32:04 +0900510static enum ssl_hs_wait_t do_send_server_finished(SSL_HANDSHAKE *hs) {
511 if (!tls13_prepare_finished(hs->ssl)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400512 return ssl_hs_error;
513 }
514
515 hs->state = state_flush;
516 return ssl_hs_write_message;
517}
518
David Benjaminc3c88822016-11-14 10:32:04 +0900519static enum ssl_hs_wait_t do_flush(SSL_HANDSHAKE *hs) {
520 SSL *const ssl = hs->ssl;
Steven Valdez143e8b32016-07-11 13:19:03 -0400521 /* Update the secret to the master secret and derive traffic keys. */
Steven Valdez143e8b32016-07-11 13:19:03 -0400522 if (!tls13_advance_key_schedule(ssl, kZeroes, hs->hash_len) ||
Steven Valdeza833c352016-11-01 13:39:36 -0400523 !tls13_derive_application_secrets(ssl) ||
524 !tls13_set_traffic_key(ssl, evp_aead_seal, hs->server_traffic_secret_0,
525 hs->hash_len)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400526 return ssl_hs_error;
527 }
528
529 hs->state = state_process_client_certificate;
David Benjaminf2401eb2016-07-18 22:25:05 +0200530 return ssl_hs_flush_and_read_message;
Steven Valdez143e8b32016-07-11 13:19:03 -0400531}
532
David Benjaminc3c88822016-11-14 10:32:04 +0900533static enum ssl_hs_wait_t do_process_client_certificate(SSL_HANDSHAKE *hs) {
534 SSL *const ssl = hs->ssl;
535 if (!hs->cert_request) {
Adam Langley37646832016-08-01 16:16:46 -0700536 /* OpenSSL returns X509_V_OK when no certificates are requested. This is
David Benjamindd634eb2016-08-18 16:40:28 -0400537 * classed by them as a bug, but it's assumed by at least NGINX. */
Adam Langley37646832016-08-01 16:16:46 -0700538 ssl->s3->new_session->verify_result = X509_V_OK;
539
Steven Valdez143e8b32016-07-11 13:19:03 -0400540 /* Skip this state. */
Nick Harper60a85cb2016-09-23 16:25:11 -0700541 hs->state = state_process_channel_id;
Steven Valdez143e8b32016-07-11 13:19:03 -0400542 return ssl_hs_ok;
543 }
544
David Benjamin4087df92016-08-01 20:16:31 -0400545 const int allow_anonymous =
546 (ssl->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) == 0;
547
Steven Valdez143e8b32016-07-11 13:19:03 -0400548 if (!tls13_check_message_type(ssl, SSL3_MT_CERTIFICATE) ||
David Benjamin4087df92016-08-01 20:16:31 -0400549 !tls13_process_certificate(ssl, allow_anonymous) ||
David Benjaminced94792016-11-14 17:12:11 +0900550 !ssl_hash_current_message(ssl)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400551 return ssl_hs_error;
552 }
553
David Benjamin3ce43892016-08-01 19:41:34 -0400554 /* For historical reasons, the server's copy of the chain does not include the
555 * leaf while the client's does. */
Adam Langleyc5ac2b62016-11-07 12:02:35 -0800556 if (sk_X509_num(ssl->s3->new_session->x509_chain) > 0) {
557 X509_free(sk_X509_shift(ssl->s3->new_session->x509_chain));
David Benjamin3ce43892016-08-01 19:41:34 -0400558 }
559
Steven Valdez143e8b32016-07-11 13:19:03 -0400560 hs->state = state_process_client_certificate_verify;
561 return ssl_hs_read_message;
562}
563
564static enum ssl_hs_wait_t do_process_client_certificate_verify(
David Benjaminc3c88822016-11-14 10:32:04 +0900565 SSL_HANDSHAKE *hs) {
566 SSL *const ssl = hs->ssl;
Adam Langleyc5ac2b62016-11-07 12:02:35 -0800567 if (ssl->s3->new_session->x509_peer == NULL) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400568 /* Skip this state. */
Nick Harper60a85cb2016-09-23 16:25:11 -0700569 hs->state = state_process_channel_id;
Steven Valdez143e8b32016-07-11 13:19:03 -0400570 return ssl_hs_ok;
571 }
572
573 if (!tls13_check_message_type(ssl, SSL3_MT_CERTIFICATE_VERIFY) ||
574 !tls13_process_certificate_verify(ssl) ||
David Benjaminced94792016-11-14 17:12:11 +0900575 !ssl_hash_current_message(ssl)) {
David Benjamin6929f272016-11-16 19:10:08 +0900576 return ssl_hs_error;
Steven Valdez143e8b32016-07-11 13:19:03 -0400577 }
578
Nick Harper60a85cb2016-09-23 16:25:11 -0700579 hs->state = state_process_channel_id;
580 return ssl_hs_read_message;
581}
582
David Benjaminc3c88822016-11-14 10:32:04 +0900583static enum ssl_hs_wait_t do_process_channel_id(SSL_HANDSHAKE *hs) {
584 SSL *const ssl = hs->ssl;
Nick Harper60a85cb2016-09-23 16:25:11 -0700585 if (!ssl->s3->tlsext_channel_id_valid) {
586 hs->state = state_process_client_finished;
587 return ssl_hs_ok;
588 }
589
590 if (!tls13_check_message_type(ssl, SSL3_MT_CHANNEL_ID) ||
591 !tls1_verify_channel_id(ssl) ||
David Benjaminced94792016-11-14 17:12:11 +0900592 !ssl_hash_current_message(ssl)) {
Nick Harper60a85cb2016-09-23 16:25:11 -0700593 return ssl_hs_error;
594 }
595
Steven Valdez143e8b32016-07-11 13:19:03 -0400596 hs->state = state_process_client_finished;
597 return ssl_hs_read_message;
598}
599
David Benjaminc3c88822016-11-14 10:32:04 +0900600static enum ssl_hs_wait_t do_process_client_finished(SSL_HANDSHAKE *hs) {
601 SSL *const ssl = hs->ssl;
Steven Valdez143e8b32016-07-11 13:19:03 -0400602 if (!tls13_check_message_type(ssl, SSL3_MT_FINISHED) ||
603 !tls13_process_finished(ssl) ||
David Benjaminced94792016-11-14 17:12:11 +0900604 !ssl_hash_current_message(ssl) ||
Steven Valdez143e8b32016-07-11 13:19:03 -0400605 /* evp_aead_seal keys have already been switched. */
Steven Valdeza833c352016-11-01 13:39:36 -0400606 !tls13_set_traffic_key(ssl, evp_aead_open, hs->client_traffic_secret_0,
607 hs->hash_len) ||
608 !tls13_derive_resumption_secret(ssl)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400609 return ssl_hs_error;
610 }
611
David Benjamin613fe3b2016-07-22 17:39:29 +0200612 ssl->method->received_flight(ssl);
David Benjamin123db572016-11-03 16:59:25 -0400613
614 /* Refresh the session timestamp so that it is measured from ticket
615 * issuance. */
616 ssl_session_refresh_time(ssl, ssl->s3->new_session);
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400617 hs->state = state_send_new_session_ticket;
Steven Valdez143e8b32016-07-11 13:19:03 -0400618 return ssl_hs_ok;
619}
620
David Benjamin0a011fc2016-11-03 17:19:16 -0400621/* TLS 1.3 recommends single-use tickets, so issue multiple tickets in case the
622 * client makes several connections before getting a renewal. */
623static const int kNumTickets = 2;
624
David Benjaminc3c88822016-11-14 10:32:04 +0900625static enum ssl_hs_wait_t do_send_new_session_ticket(SSL_HANDSHAKE *hs) {
626 SSL *const ssl = hs->ssl;
Steven Valdeza833c352016-11-01 13:39:36 -0400627 /* If the client doesn't accept resumption with PSK_DHE_KE, don't send a
628 * session ticket. */
629 if (!hs->accept_psk_mode) {
630 hs->state = state_done;
631 return ssl_hs_ok;
632 }
633
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400634 SSL_SESSION *session = ssl->s3->new_session;
Steven Valdeza833c352016-11-01 13:39:36 -0400635 if (!RAND_bytes((uint8_t *)&session->ticket_age_add, 4)) {
636 goto err;
637 }
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400638
Steven Valdez5b986082016-09-01 12:29:49 -0400639 /* TODO(svaldez): Add support for sending 0RTT through TicketEarlyDataInfo
640 * extension. */
641
Steven Valdeza833c352016-11-01 13:39:36 -0400642 CBB cbb, body, ticket, extensions;
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400643 if (!ssl->method->init_message(ssl, &cbb, &body,
644 SSL3_MT_NEW_SESSION_TICKET) ||
David Benjamin123db572016-11-03 16:59:25 -0400645 !CBB_add_u32(&body, session->timeout) ||
Steven Valdeza833c352016-11-01 13:39:36 -0400646 !CBB_add_u32(&body, session->ticket_age_add) ||
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400647 !CBB_add_u16_length_prefixed(&body, &ticket) ||
648 !ssl_encrypt_ticket(ssl, &ticket, session) ||
David Benjamin1a5e8ec2016-10-07 15:19:18 -0400649 !CBB_add_u16_length_prefixed(&body, &extensions)) {
650 goto err;
651 }
652
653 /* Add a fake extension. See draft-davidben-tls-grease-01. */
David Benjamin079b3942016-10-20 13:19:20 -0400654 if (!CBB_add_u16(&extensions,
655 ssl_get_grease_value(ssl, ssl_grease_ticket_extension)) ||
656 !CBB_add_u16(&extensions, 0 /* empty */)) {
657 goto err;
David Benjamin1a5e8ec2016-10-07 15:19:18 -0400658 }
659
Steven Valdez5eead162016-11-11 22:23:25 -0500660 if (!ssl_complete_message(ssl, &cbb)) {
David Benjamin1a5e8ec2016-10-07 15:19:18 -0400661 goto err;
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400662 }
663
664 hs->session_tickets_sent++;
David Benjamin0a011fc2016-11-03 17:19:16 -0400665 if (hs->session_tickets_sent >= kNumTickets) {
666 hs->state = state_flush_new_session_tickets;
667 } else {
668 hs->state = state_send_new_session_ticket;
669 }
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400670
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400671 return ssl_hs_write_message;
David Benjamin1a5e8ec2016-10-07 15:19:18 -0400672
673err:
674 CBB_cleanup(&cbb);
675 return ssl_hs_error;
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400676}
677
David Benjaminc3c88822016-11-14 10:32:04 +0900678static enum ssl_hs_wait_t do_flush_new_session_tickets(SSL_HANDSHAKE *hs) {
David Benjamin0a011fc2016-11-03 17:19:16 -0400679 hs->state = state_done;
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400680 return ssl_hs_flush;
681}
682
David Benjaminc3c88822016-11-14 10:32:04 +0900683enum ssl_hs_wait_t tls13_server_handshake(SSL_HANDSHAKE *hs) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400684 while (hs->state != state_done) {
685 enum ssl_hs_wait_t ret = ssl_hs_error;
686 enum server_hs_state_t state = hs->state;
687 switch (state) {
688 case state_process_client_hello:
David Benjaminc3c88822016-11-14 10:32:04 +0900689 ret = do_process_client_hello(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400690 break;
David Benjamin25fe85b2016-08-09 20:00:32 -0400691 case state_select_parameters:
David Benjaminc3c88822016-11-14 10:32:04 +0900692 ret = do_select_parameters(hs);
David Benjamin25fe85b2016-08-09 20:00:32 -0400693 break;
Steven Valdez5440fe02016-07-18 12:40:30 -0400694 case state_send_hello_retry_request:
David Benjaminc3c88822016-11-14 10:32:04 +0900695 ret = do_send_hello_retry_request(hs);
Steven Valdez5440fe02016-07-18 12:40:30 -0400696 break;
697 case state_flush_hello_retry_request:
David Benjaminc3c88822016-11-14 10:32:04 +0900698 ret = do_flush_hello_retry_request(hs);
Steven Valdez5440fe02016-07-18 12:40:30 -0400699 break;
700 case state_process_second_client_hello:
David Benjaminc3c88822016-11-14 10:32:04 +0900701 ret = do_process_second_client_hello(hs);
Steven Valdez5440fe02016-07-18 12:40:30 -0400702 break;
Steven Valdez143e8b32016-07-11 13:19:03 -0400703 case state_send_server_hello:
David Benjaminc3c88822016-11-14 10:32:04 +0900704 ret = do_send_server_hello(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400705 break;
706 case state_send_encrypted_extensions:
David Benjaminc3c88822016-11-14 10:32:04 +0900707 ret = do_send_encrypted_extensions(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400708 break;
709 case state_send_certificate_request:
David Benjaminc3c88822016-11-14 10:32:04 +0900710 ret = do_send_certificate_request(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400711 break;
712 case state_send_server_certificate:
David Benjaminc3c88822016-11-14 10:32:04 +0900713 ret = do_send_server_certificate(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400714 break;
715 case state_send_server_certificate_verify:
David Benjaminc3c88822016-11-14 10:32:04 +0900716 ret = do_send_server_certificate_verify(hs, 1 /* first run */);
Steven Valdez143e8b32016-07-11 13:19:03 -0400717 break;
718 case state_complete_server_certificate_verify:
David Benjaminc3c88822016-11-14 10:32:04 +0900719 ret = do_send_server_certificate_verify(hs, 0 /* complete */);
Steven Valdez143e8b32016-07-11 13:19:03 -0400720 break;
721 case state_send_server_finished:
David Benjaminc3c88822016-11-14 10:32:04 +0900722 ret = do_send_server_finished(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400723 break;
724 case state_flush:
David Benjaminc3c88822016-11-14 10:32:04 +0900725 ret = do_flush(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400726 break;
Steven Valdez143e8b32016-07-11 13:19:03 -0400727 case state_process_client_certificate:
David Benjaminc3c88822016-11-14 10:32:04 +0900728 ret = do_process_client_certificate(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400729 break;
730 case state_process_client_certificate_verify:
David Benjaminc3c88822016-11-14 10:32:04 +0900731 ret = do_process_client_certificate_verify(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400732 break;
Nick Harper60a85cb2016-09-23 16:25:11 -0700733 case state_process_channel_id:
David Benjaminc3c88822016-11-14 10:32:04 +0900734 ret = do_process_channel_id(hs);
Nick Harper60a85cb2016-09-23 16:25:11 -0700735 break;
Steven Valdez143e8b32016-07-11 13:19:03 -0400736 case state_process_client_finished:
David Benjaminc3c88822016-11-14 10:32:04 +0900737 ret = do_process_client_finished(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400738 break;
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400739 case state_send_new_session_ticket:
David Benjaminc3c88822016-11-14 10:32:04 +0900740 ret = do_send_new_session_ticket(hs);
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400741 break;
David Benjamin0a011fc2016-11-03 17:19:16 -0400742 case state_flush_new_session_tickets:
David Benjaminc3c88822016-11-14 10:32:04 +0900743 ret = do_flush_new_session_tickets(hs);
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400744 break;
Steven Valdez143e8b32016-07-11 13:19:03 -0400745 case state_done:
746 ret = ssl_hs_ok;
747 break;
748 }
749
750 if (ret != ssl_hs_ok) {
751 return ret;
752 }
753 }
754
755 return ssl_hs_ok;
756}