blob: aa80b69202d7fbafde2c5f822f53c1e458ae8ebe [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
20#include <openssl/bytestring.h>
21#include <openssl/digest.h>
22#include <openssl/err.h>
23#include <openssl/mem.h>
24#include <openssl/stack.h>
25#include <openssl/x509.h>
26
27#include "internal.h"
28
29
30enum client_hs_state_t {
Steven Valdez5440fe02016-07-18 12:40:30 -040031 state_process_hello_retry_request = 0,
32 state_send_second_client_hello,
33 state_flush_second_client_hello,
34 state_process_server_hello,
Steven Valdez143e8b32016-07-11 13:19:03 -040035 state_process_encrypted_extensions,
36 state_process_certificate_request,
37 state_process_server_certificate,
38 state_process_server_certificate_verify,
39 state_process_server_finished,
40 state_certificate_callback,
41 state_send_client_certificate,
42 state_send_client_certificate_verify,
43 state_complete_client_certificate_verify,
44 state_send_client_finished,
45 state_flush,
46 state_done,
47};
48
Steven Valdez5440fe02016-07-18 12:40:30 -040049static enum ssl_hs_wait_t do_process_hello_retry_request(SSL *ssl,
50 SSL_HANDSHAKE *hs) {
51 if (ssl->s3->tmp.message_type != SSL3_MT_HELLO_RETRY_REQUEST) {
52 hs->state = state_process_server_hello;
53 return ssl_hs_ok;
54 }
55
56 CBS cbs, extensions;
57 uint16_t server_wire_version, cipher_suite, group_id;
58 CBS_init(&cbs, ssl->init_msg, ssl->init_num);
59 if (!CBS_get_u16(&cbs, &server_wire_version) ||
60 !CBS_get_u16(&cbs, &cipher_suite) ||
61 !CBS_get_u16(&cbs, &group_id) ||
62 /* We do not currently parse any HelloRetryRequest extensions. */
63 !CBS_get_u16_length_prefixed(&cbs, &extensions) ||
64 CBS_len(&cbs) != 0) {
65 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
66 return ssl_hs_error;
67 }
68
69 /* TODO(svaldez): Don't do early_data on HelloRetryRequest. */
70
71 const uint16_t *groups;
72 size_t groups_len;
73 tls1_get_grouplist(ssl, 0 /* local groups */, &groups, &groups_len);
74 int found = 0;
75 for (size_t i = 0; i < groups_len; i++) {
76 if (groups[i] == group_id) {
77 found = 1;
78 break;
79 }
80 }
81
82 if (!found) {
83 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
84 OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CURVE);
85 return ssl_hs_error;
86 }
87
David Benjaminc8b6b4f2016-09-08 23:47:48 -040088 /* Check that the HelloRetryRequest does not request the key share that was
89 * provided in the initial ClientHello. */
90 if (SSL_ECDH_CTX_get_id(&ssl->s3->hs->ecdh_ctx) == group_id) {
91 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
92 OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CURVE);
93 return ssl_hs_error;
Steven Valdez5440fe02016-07-18 12:40:30 -040094 }
95
David Benjaminc8b6b4f2016-09-08 23:47:48 -040096 SSL_ECDH_CTX_cleanup(&ssl->s3->hs->ecdh_ctx);
Steven Valdez5440fe02016-07-18 12:40:30 -040097 ssl->s3->hs->retry_group = group_id;
98
99 hs->state = state_send_second_client_hello;
100 return ssl_hs_ok;
101}
102
103static enum ssl_hs_wait_t do_send_second_client_hello(SSL *ssl,
104 SSL_HANDSHAKE *hs) {
105 CBB cbb, body;
106 if (!ssl->method->init_message(ssl, &cbb, &body, SSL3_MT_CLIENT_HELLO) ||
107 !ssl_add_client_hello_body(ssl, &body) ||
108 !ssl->method->finish_message(ssl, &cbb)) {
109 CBB_cleanup(&cbb);
110 return ssl_hs_error;
111 }
112
113 hs->state = state_flush_second_client_hello;
114 return ssl_hs_write_message;
115}
116
117static enum ssl_hs_wait_t do_flush_second_client_hello(SSL *ssl,
118 SSL_HANDSHAKE *hs) {
119 hs->state = state_process_server_hello;
120 return ssl_hs_flush_and_read_message;
121}
122
Steven Valdez143e8b32016-07-11 13:19:03 -0400123static enum ssl_hs_wait_t do_process_server_hello(SSL *ssl, SSL_HANDSHAKE *hs) {
124 if (!tls13_check_message_type(ssl, SSL3_MT_SERVER_HELLO)) {
125 return ssl_hs_error;
126 }
127
128 CBS cbs, server_random, extensions;
129 uint16_t server_wire_version;
130 uint16_t cipher_suite;
131 CBS_init(&cbs, ssl->init_msg, ssl->init_num);
132 if (!CBS_get_u16(&cbs, &server_wire_version) ||
133 !CBS_get_bytes(&cbs, &server_random, SSL3_RANDOM_SIZE) ||
134 !CBS_get_u16(&cbs, &cipher_suite) ||
135 !CBS_get_u16_length_prefixed(&cbs, &extensions) ||
136 CBS_len(&cbs) != 0) {
137 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
Steven Valdez5440fe02016-07-18 12:40:30 -0400138 OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
139 return ssl_hs_error;
140 }
141
142 if (server_wire_version != ssl->version) {
143 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
144 OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_VERSION_NUMBER);
Steven Valdez143e8b32016-07-11 13:19:03 -0400145 return ssl_hs_error;
146 }
147
148 /* Parse out the extensions. */
Steven Valdez4aa154e2016-07-29 14:32:55 -0400149 int have_key_share = 0, have_pre_shared_key = 0;
150 CBS key_share, pre_shared_key;
Steven Valdez143e8b32016-07-11 13:19:03 -0400151 while (CBS_len(&extensions) != 0) {
152 uint16_t type;
153 CBS extension;
154 if (!CBS_get_u16(&extensions, &type) ||
155 !CBS_get_u16_length_prefixed(&extensions, &extension)) {
156 OPENSSL_PUT_ERROR(SSL, SSL_R_PARSE_TLSEXT);
157 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
158 return ssl_hs_error;
159 }
160
161 switch (type) {
162 case TLSEXT_TYPE_key_share:
163 if (have_key_share) {
164 OPENSSL_PUT_ERROR(SSL, SSL_R_DUPLICATE_EXTENSION);
165 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
166 return ssl_hs_error;
167 }
168 key_share = extension;
169 have_key_share = 1;
170 break;
Steven Valdez4aa154e2016-07-29 14:32:55 -0400171 case TLSEXT_TYPE_pre_shared_key:
172 if (have_pre_shared_key) {
173 OPENSSL_PUT_ERROR(SSL, SSL_R_DUPLICATE_EXTENSION);
174 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
175 return ssl_hs_error;
176 }
177 pre_shared_key = extension;
178 have_pre_shared_key = 1;
179 break;
Steven Valdez143e8b32016-07-11 13:19:03 -0400180 default:
181 OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION);
182 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNSUPPORTED_EXTENSION);
183 return ssl_hs_error;
184 }
185 }
186
187 assert(ssl->s3->have_version);
188 memcpy(ssl->s3->server_random, CBS_data(&server_random), SSL3_RANDOM_SIZE);
189
Steven Valdez4aa154e2016-07-29 14:32:55 -0400190 uint8_t alert = SSL_AD_DECODE_ERROR;
191 if (have_pre_shared_key) {
192 if (ssl->session == NULL) {
193 OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION);
194 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNSUPPORTED_EXTENSION);
195 return ssl_hs_error;
196 }
197
198 if (!ssl_ext_pre_shared_key_parse_serverhello(ssl, &alert,
199 &pre_shared_key)) {
200 ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
201 return ssl_hs_error;
202 }
203
204 if (ssl->session->ssl_version != ssl->version) {
205 OPENSSL_PUT_ERROR(SSL, SSL_R_OLD_SESSION_VERSION_NOT_RETURNED);
206 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
207 return ssl_hs_error;
208 }
209
210 if (!ssl_session_is_context_valid(ssl, ssl->session)) {
211 /* This is actually a client application bug. */
212 OPENSSL_PUT_ERROR(SSL,
213 SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT);
214 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
215 return ssl_hs_error;
216 }
217
218 ssl->s3->session_reused = 1;
219 /* Only authentication information carries over in TLS 1.3. */
220 ssl->s3->new_session =
221 SSL_SESSION_dup(ssl->session, SSL_SESSION_DUP_AUTH_ONLY);
222 if (ssl->s3->new_session == NULL) {
223 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
224 return ssl_hs_error;
225 }
David Benjamin4d0be242016-09-01 01:10:07 -0400226 ssl_set_session(ssl, NULL);
Steven Valdez4aa154e2016-07-29 14:32:55 -0400227 } else {
228 if (!ssl_get_new_session(ssl, 0)) {
229 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
230 return ssl_hs_error;
231 }
Steven Valdez143e8b32016-07-11 13:19:03 -0400232 }
233
234 const SSL_CIPHER *cipher = SSL_get_cipher_by_value(cipher_suite);
235 if (cipher == NULL) {
236 OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CIPHER_RETURNED);
237 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
238 return ssl_hs_error;
239 }
240
Steven Valdez4aa154e2016-07-29 14:32:55 -0400241 if (!ssl->s3->session_reused) {
242 /* Check if the cipher is disabled. */
243 if ((cipher->algorithm_mkey & ssl->cert->mask_k) ||
244 (cipher->algorithm_auth & ssl->cert->mask_a) ||
245 SSL_CIPHER_get_min_version(cipher) > ssl3_protocol_version(ssl) ||
246 SSL_CIPHER_get_max_version(cipher) < ssl3_protocol_version(ssl) ||
247 !sk_SSL_CIPHER_find(ssl_get_ciphers_by_id(ssl), NULL, cipher)) {
248 OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CIPHER_RETURNED);
249 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
250 return ssl_hs_error;
251 }
252 } else {
253 uint16_t resumption_cipher;
254 if (!ssl_cipher_get_ecdhe_psk_cipher(ssl->s3->new_session->cipher,
255 &resumption_cipher) ||
256 resumption_cipher != ssl_cipher_get_value(cipher)) {
257 OPENSSL_PUT_ERROR(SSL, SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED);
258 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
259 return ssl_hs_error;
260 }
Steven Valdez143e8b32016-07-11 13:19:03 -0400261 }
262
Steven Valdez87eab492016-06-27 16:34:59 -0400263 ssl->s3->new_session->cipher = cipher;
Steven Valdez143e8b32016-07-11 13:19:03 -0400264 ssl->s3->tmp.new_cipher = cipher;
265
266 /* The PRF hash is now known. Set up the key schedule. */
267 static const uint8_t kZeroes[EVP_MAX_MD_SIZE] = {0};
Steven Valdez4aa154e2016-07-29 14:32:55 -0400268 size_t resumption_ctx_len =
Steven Valdez143e8b32016-07-11 13:19:03 -0400269 EVP_MD_size(ssl_get_handshake_digest(ssl_get_algorithm_prf(ssl)));
Steven Valdez4aa154e2016-07-29 14:32:55 -0400270 if (ssl->s3->session_reused) {
271 uint8_t resumption_ctx[EVP_MAX_MD_SIZE];
272 if (!tls13_resumption_context(ssl, resumption_ctx, resumption_ctx_len,
273 ssl->s3->new_session) ||
274 !tls13_init_key_schedule(ssl, resumption_ctx, resumption_ctx_len)) {
275 return ssl_hs_error;
276 }
277 } else if (!tls13_init_key_schedule(ssl, kZeroes, resumption_ctx_len)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400278 return ssl_hs_error;
279 }
280
281 /* Resolve PSK and incorporate it into the secret. */
282 if (cipher->algorithm_auth == SSL_aPSK) {
Steven Valdez4aa154e2016-07-29 14:32:55 -0400283 if (!ssl->s3->session_reused) {
284 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
285 return ssl_hs_error;
286 }
287
288 uint8_t resumption_psk[EVP_MAX_MD_SIZE];
289 if (!tls13_resumption_psk(ssl, resumption_psk, hs->hash_len,
290 ssl->s3->new_session) ||
291 !tls13_advance_key_schedule(ssl, resumption_psk, hs->hash_len)) {
292 OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
293 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
294 return ssl_hs_error;
295 }
296 } else if (!tls13_advance_key_schedule(ssl, kZeroes, hs->hash_len)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400297 return ssl_hs_error;
298 }
299
300 /* Resolve ECDHE and incorporate it into the secret. */
301 if (cipher->algorithm_mkey == SSL_kECDHE) {
302 if (!have_key_share) {
303 OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_KEY_SHARE);
304 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_MISSING_EXTENSION);
305 return ssl_hs_error;
306 }
307
308 uint8_t *dhe_secret;
309 size_t dhe_secret_len;
Steven Valdez7259f2f2016-08-02 16:55:05 -0400310 if (!ssl_ext_key_share_parse_serverhello(ssl, &dhe_secret, &dhe_secret_len,
311 &alert, &key_share)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400312 ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
313 return ssl_hs_error;
314 }
315
316 int ok = tls13_advance_key_schedule(ssl, dhe_secret, dhe_secret_len);
317 OPENSSL_free(dhe_secret);
318 if (!ok) {
319 return ssl_hs_error;
320 }
321 } else {
322 if (have_key_share) {
323 OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION);
324 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNSUPPORTED_EXTENSION);
325 return ssl_hs_error;
326 }
Steven Valdez4aa154e2016-07-29 14:32:55 -0400327 if (!tls13_advance_key_schedule(ssl, kZeroes, hs->hash_len)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400328 return ssl_hs_error;
329 }
Steven Valdez5440fe02016-07-18 12:40:30 -0400330 }
331
332 /* If there was no HelloRetryRequest, the version negotiation logic has
333 * already hashed the message. */
334 if (ssl->s3->hs->retry_group != 0 &&
335 !ssl->method->hash_current_message(ssl)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400336 return ssl_hs_error;
337 }
338
339 if (!tls13_set_handshake_traffic(ssl)) {
340 return ssl_hs_error;
341 }
342
343 hs->state = state_process_encrypted_extensions;
344 return ssl_hs_read_message;
345}
346
347static enum ssl_hs_wait_t do_process_encrypted_extensions(SSL *ssl,
348 SSL_HANDSHAKE *hs) {
349 if (!tls13_check_message_type(ssl, SSL3_MT_ENCRYPTED_EXTENSIONS)) {
350 return ssl_hs_error;
351 }
352
353 CBS cbs;
354 CBS_init(&cbs, ssl->init_msg, ssl->init_num);
355 if (!ssl_parse_serverhello_tlsext(ssl, &cbs)) {
356 OPENSSL_PUT_ERROR(SSL, SSL_R_PARSE_TLSEXT);
357 return ssl_hs_error;
358 }
359 if (CBS_len(&cbs) != 0) {
360 OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
361 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
362 return ssl_hs_error;
363 }
364
365 if (!ssl->method->hash_current_message(ssl)) {
366 return ssl_hs_error;
367 }
368
369 hs->state = state_process_certificate_request;
370 return ssl_hs_read_message;
371}
372
373static enum ssl_hs_wait_t do_process_certificate_request(SSL *ssl,
374 SSL_HANDSHAKE *hs) {
375 ssl->s3->tmp.cert_request = 0;
376
377 /* CertificateRequest may only be sent in certificate-based ciphers. */
David Benjamin3d458dc2016-09-12 22:40:27 +0000378 if (!ssl_cipher_uses_certificate_auth(ssl->s3->tmp.new_cipher)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400379 hs->state = state_process_server_finished;
380 return ssl_hs_ok;
381 }
382
383 /* CertificateRequest is optional. */
384 if (ssl->s3->tmp.message_type != SSL3_MT_CERTIFICATE_REQUEST) {
385 hs->state = state_process_server_certificate;
386 return ssl_hs_ok;
387 }
388
389 CBS cbs, context, supported_signature_algorithms;
390 CBS_init(&cbs, ssl->init_msg, ssl->init_num);
391 if (!CBS_get_u8_length_prefixed(&cbs, &context) ||
David Benjamin8a8349b2016-08-18 02:32:23 -0400392 /* The request context is always empty during the handshake. */
393 CBS_len(&context) != 0 ||
Steven Valdez143e8b32016-07-11 13:19:03 -0400394 !CBS_get_u16_length_prefixed(&cbs, &supported_signature_algorithms) ||
David Benjamin48901652016-08-01 12:12:47 -0400395 CBS_len(&supported_signature_algorithms) == 0 ||
Steven Valdez143e8b32016-07-11 13:19:03 -0400396 !tls1_parse_peer_sigalgs(ssl, &supported_signature_algorithms)) {
397 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
398 OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
399 return ssl_hs_error;
400 }
401
402 uint8_t alert;
403 STACK_OF(X509_NAME) *ca_sk = ssl_parse_client_CA_list(ssl, &alert, &cbs);
404 if (ca_sk == NULL) {
405 ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
406 return ssl_hs_error;
407 }
408
409 /* Ignore extensions. */
410 CBS extensions;
411 if (!CBS_get_u16_length_prefixed(&cbs, &extensions) ||
412 CBS_len(&cbs) != 0) {
413 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
David Benjamin639846e2016-09-09 11:41:18 -0400414 sk_X509_NAME_pop_free(ca_sk, X509_NAME_free);
Steven Valdez143e8b32016-07-11 13:19:03 -0400415 OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
416 return ssl_hs_error;
417 }
418
419 ssl->s3->tmp.cert_request = 1;
420 sk_X509_NAME_pop_free(ssl->s3->tmp.ca_names, X509_NAME_free);
421 ssl->s3->tmp.ca_names = ca_sk;
422
423 if (!ssl->method->hash_current_message(ssl)) {
424 return ssl_hs_error;
425 }
426
427 hs->state = state_process_server_certificate;
428 return ssl_hs_read_message;
429}
430
431static enum ssl_hs_wait_t do_process_server_certificate(SSL *ssl,
432 SSL_HANDSHAKE *hs) {
433 if (!tls13_check_message_type(ssl, SSL3_MT_CERTIFICATE) ||
David Benjamin4087df92016-08-01 20:16:31 -0400434 !tls13_process_certificate(ssl, 0 /* certificate required */) ||
Steven Valdez143e8b32016-07-11 13:19:03 -0400435 !ssl->method->hash_current_message(ssl)) {
436 return ssl_hs_error;
437 }
438
David Benjamin3ce43892016-08-01 19:41:34 -0400439 /* Check the certificate matches the cipher suite.
440 *
441 * TODO(davidben): Remove this check when switching to the new TLS 1.3 cipher
442 * suite negotiation. */
443 if (!ssl_check_leaf_certificate(ssl, ssl->s3->new_session->peer)) {
444 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
445 return ssl_hs_error;
446 }
447
Steven Valdez143e8b32016-07-11 13:19:03 -0400448 hs->state = state_process_server_certificate_verify;
449 return ssl_hs_read_message;
450}
451
452static enum ssl_hs_wait_t do_process_server_certificate_verify(
453 SSL *ssl, SSL_HANDSHAKE *hs) {
454 if (!tls13_check_message_type(ssl, SSL3_MT_CERTIFICATE_VERIFY) ||
455 !tls13_process_certificate_verify(ssl) ||
456 !ssl->method->hash_current_message(ssl)) {
457 return 0;
458 }
459
460 hs->state = state_process_server_finished;
461 return ssl_hs_read_message;
462}
463
464static enum ssl_hs_wait_t do_process_server_finished(SSL *ssl,
465 SSL_HANDSHAKE *hs) {
466 static const uint8_t kZeroes[EVP_MAX_MD_SIZE] = {0};
467
468 if (!tls13_check_message_type(ssl, SSL3_MT_FINISHED) ||
469 !tls13_process_finished(ssl) ||
470 !ssl->method->hash_current_message(ssl) ||
471 /* Update the secret to the master secret and derive traffic keys. */
472 !tls13_advance_key_schedule(ssl, kZeroes, hs->hash_len) ||
473 !tls13_derive_traffic_secret_0(ssl)) {
474 return ssl_hs_error;
475 }
476
David Benjamin613fe3b2016-07-22 17:39:29 +0200477 ssl->method->received_flight(ssl);
Steven Valdez143e8b32016-07-11 13:19:03 -0400478 hs->state = state_certificate_callback;
479 return ssl_hs_ok;
480}
481
482static enum ssl_hs_wait_t do_certificate_callback(SSL *ssl, SSL_HANDSHAKE *hs) {
483 /* The peer didn't request a certificate. */
484 if (!ssl->s3->tmp.cert_request) {
485 hs->state = state_send_client_finished;
486 return ssl_hs_ok;
487 }
488
489 /* Call cert_cb to update the certificate. */
490 if (ssl->cert->cert_cb != NULL) {
491 int rv = ssl->cert->cert_cb(ssl, ssl->cert->cert_cb_arg);
492 if (rv == 0) {
493 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
494 OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_CB_ERROR);
495 return ssl_hs_error;
496 }
497 if (rv < 0) {
498 hs->state = state_certificate_callback;
499 return ssl_hs_x509_lookup;
500 }
501 }
502
503 hs->state = state_send_client_certificate;
504 return ssl_hs_ok;
505}
506
507static enum ssl_hs_wait_t do_send_client_certificate(SSL *ssl,
508 SSL_HANDSHAKE *hs) {
David Benjamin13f1ebe2016-07-20 10:11:04 +0200509 /* Call client_cert_cb to update the certificate. */
510 int should_retry;
511 if (!ssl_do_client_cert_cb(ssl, &should_retry)) {
512 if (should_retry) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400513 hs->state = state_send_client_certificate;
514 return ssl_hs_x509_lookup;
515 }
David Benjamin13f1ebe2016-07-20 10:11:04 +0200516 return ssl_hs_error;
Steven Valdez143e8b32016-07-11 13:19:03 -0400517 }
518
519 if (!tls13_prepare_certificate(ssl)) {
520 return ssl_hs_error;
521 }
522
523 hs->state = state_send_client_certificate_verify;
524 return ssl_hs_write_message;
525}
526
527static enum ssl_hs_wait_t do_send_client_certificate_verify(SSL *ssl,
528 SSL_HANDSHAKE *hs,
529 int is_first_run) {
530 /* Don't send CertificateVerify if there is no certificate. */
531 if (!ssl_has_certificate(ssl)) {
532 hs->state = state_send_client_finished;
533 return ssl_hs_ok;
534 }
535
536 switch (tls13_prepare_certificate_verify(ssl, is_first_run)) {
537 case ssl_private_key_success:
538 hs->state = state_send_client_finished;
539 return ssl_hs_write_message;
540
541 case ssl_private_key_retry:
542 hs->state = state_complete_client_certificate_verify;
543 return ssl_hs_private_key_operation;
544
545 case ssl_private_key_failure:
546 return ssl_hs_error;
547 }
548
549 assert(0);
550 return ssl_hs_error;
551}
552
553static enum ssl_hs_wait_t do_send_client_finished(SSL *ssl, SSL_HANDSHAKE *hs) {
554 if (!tls13_prepare_finished(ssl)) {
555 return ssl_hs_error;
556 }
557
558 hs->state = state_flush;
559 return ssl_hs_write_message;
560}
561
562static enum ssl_hs_wait_t do_flush(SSL *ssl, SSL_HANDSHAKE *hs) {
563 if (!tls13_set_traffic_key(ssl, type_data, evp_aead_open,
564 hs->traffic_secret_0, hs->hash_len) ||
565 !tls13_set_traffic_key(ssl, type_data, evp_aead_seal,
566 hs->traffic_secret_0, hs->hash_len) ||
567 !tls13_finalize_keys(ssl)) {
568 return ssl_hs_error;
569 }
570
571 hs->state = state_done;
572 return ssl_hs_flush;
573}
574
575enum ssl_hs_wait_t tls13_client_handshake(SSL *ssl) {
576 SSL_HANDSHAKE *hs = ssl->s3->hs;
577
578 while (hs->state != state_done) {
579 enum ssl_hs_wait_t ret = ssl_hs_error;
580 enum client_hs_state_t state = hs->state;
581 switch (state) {
Steven Valdez5440fe02016-07-18 12:40:30 -0400582 case state_process_hello_retry_request:
583 ret = do_process_hello_retry_request(ssl, hs);
584 break;
585 case state_send_second_client_hello:
586 ret = do_send_second_client_hello(ssl, hs);
587 break;
588 case state_flush_second_client_hello:
589 ret = do_flush_second_client_hello(ssl, hs);
590 break;
Steven Valdez143e8b32016-07-11 13:19:03 -0400591 case state_process_server_hello:
592 ret = do_process_server_hello(ssl, hs);
593 break;
594 case state_process_encrypted_extensions:
595 ret = do_process_encrypted_extensions(ssl, hs);
596 break;
597 case state_process_certificate_request:
598 ret = do_process_certificate_request(ssl, hs);
599 break;
600 case state_process_server_certificate:
601 ret = do_process_server_certificate(ssl, hs);
602 break;
603 case state_process_server_certificate_verify:
604 ret = do_process_server_certificate_verify(ssl, hs);
605 break;
606 case state_process_server_finished:
607 ret = do_process_server_finished(ssl, hs);
608 break;
609 case state_certificate_callback:
610 ret = do_certificate_callback(ssl, hs);
611 break;
612 case state_send_client_certificate:
613 ret = do_send_client_certificate(ssl, hs);
614 break;
615 case state_send_client_certificate_verify:
616 ret = do_send_client_certificate_verify(ssl, hs, 1 /* first run */);
617 break;
618 case state_complete_client_certificate_verify:
619 ret = do_send_client_certificate_verify(ssl, hs, 0 /* complete */);
620 break;
621 case state_send_client_finished:
622 ret = do_send_client_finished(ssl, hs);
623 break;
624 case state_flush:
625 ret = do_flush(ssl, hs);
626 break;
627 case state_done:
628 ret = ssl_hs_ok;
629 break;
630 }
631
632 if (ret != ssl_hs_ok) {
633 return ret;
634 }
635 }
636
637 return ssl_hs_ok;
638}
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400639
640int tls13_process_new_session_ticket(SSL *ssl) {
Steven Valdez4aa154e2016-07-29 14:32:55 -0400641 SSL_SESSION *session =
642 SSL_SESSION_dup(ssl->s3->established_session,
643 SSL_SESSION_INCLUDE_NONAUTH);
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400644 if (session == NULL) {
645 return 0;
646 }
647
Steven Valdez5b986082016-09-01 12:29:49 -0400648 CBS cbs, ke_modes, auth_modes, ticket, extensions;
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400649 CBS_init(&cbs, ssl->init_msg, ssl->init_num);
Martin Kreichgauerbaafa4a2016-08-09 10:18:40 -0700650 if (!CBS_get_u32(&cbs, &session->tlsext_tick_lifetime_hint) ||
Steven Valdez5b986082016-09-01 12:29:49 -0400651 !CBS_get_u8_length_prefixed(&cbs, &ke_modes) ||
652 CBS_len(&ke_modes) == 0 ||
653 !CBS_get_u8_length_prefixed(&cbs, &auth_modes) ||
654 CBS_len(&auth_modes) == 0 ||
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400655 !CBS_get_u16_length_prefixed(&cbs, &ticket) ||
656 !CBS_stow(&ticket, &session->tlsext_tick, &session->tlsext_ticklen) ||
Steven Valdez5b986082016-09-01 12:29:49 -0400657 !CBS_get_u16_length_prefixed(&cbs, &extensions) ||
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400658 CBS_len(&cbs) != 0) {
659 SSL_SESSION_free(session);
660 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
661 OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
662 return 0;
663 }
664
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400665 session->not_resumable = 0;
666
Steven Valdez5b986082016-09-01 12:29:49 -0400667 /* Ignore the ticket unless the server preferences are compatible with us. */
668 if (memchr(CBS_data(&ke_modes), SSL_PSK_DHE_KE, CBS_len(&ke_modes)) != NULL &&
669 memchr(CBS_data(&auth_modes), SSL_PSK_AUTH, CBS_len(&auth_modes)) !=
670 NULL &&
671 ssl->ctx->new_session_cb != NULL &&
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400672 ssl->ctx->new_session_cb(ssl, session)) {
673 /* |new_session_cb|'s return value signals that it took ownership. */
674 return 1;
675 }
676
677 SSL_SESSION_free(session);
678 return 1;
679}
David Benjamin4fe3c902016-08-16 02:17:03 -0400680
681void ssl_clear_tls13_state(SSL *ssl) {
David Benjaminc8b6b4f2016-09-08 23:47:48 -0400682 SSL_ECDH_CTX_cleanup(&ssl->s3->hs->ecdh_ctx);
David Benjamin4fe3c902016-08-16 02:17:03 -0400683
684 OPENSSL_free(ssl->s3->hs->key_share_bytes);
685 ssl->s3->hs->key_share_bytes = NULL;
686 ssl->s3->hs->key_share_bytes_len = 0;
687}