From 066904cceef26bbb5c63c237d20829fb0db82ddc Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Wed, 8 Nov 2017 14:26:48 +0000 Subject: [PATCH] Send a CCS from a client in an early_data handshake Reviewed-by: Ben Kaduk (Merged from https://github.com/openssl/openssl/pull/4701) --- ssl/statem/statem_clnt.c | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/ssl/statem/statem_clnt.c b/ssl/statem/statem_clnt.c index 91fb13d805..37c198e713 100644 --- a/ssl/statem/statem_clnt.c +++ b/ssl/statem/statem_clnt.c @@ -494,7 +494,10 @@ WRITE_TRAN ossl_statem_client_write_transition(SSL *s) * We are assuming this is a TLSv1.3 connection, although we haven't * actually selected a version yet. */ - st->hand_state = TLS_ST_EARLY_DATA; + if ((s->options & SSL_OP_ENABLE_MIDDLEBOX_COMPAT) != 0) + st->hand_state = TLS_ST_CW_CHANGE; + else + st->hand_state = TLS_ST_EARLY_DATA; return WRITE_TRAN_CONTINUE; } /* @@ -551,15 +554,18 @@ WRITE_TRAN ossl_statem_client_write_transition(SSL *s) return WRITE_TRAN_CONTINUE; case TLS_ST_CW_CHANGE: + if (s->early_data_state == SSL_EARLY_DATA_CONNECTING) { + st->hand_state = TLS_ST_EARLY_DATA; + } else { #if defined(OPENSSL_NO_NEXTPROTONEG) - st-> - hand_state = TLS_ST_CW_FINISHED; -#else - if (!SSL_IS_DTLS(s) && s->s3->npn_seen) - st->hand_state = TLS_ST_CW_NEXT_PROTO; - else st->hand_state = TLS_ST_CW_FINISHED; +#else + if (!SSL_IS_DTLS(s) && s->s3->npn_seen) + st->hand_state = TLS_ST_CW_NEXT_PROTO; + else + st->hand_state = TLS_ST_CW_FINISHED; #endif + } return WRITE_TRAN_CONTINUE; #if !defined(OPENSSL_NO_NEXTPROTONEG) @@ -690,7 +696,8 @@ WORK_STATE ossl_statem_client_post_work(SSL *s, WORK_STATE wst) } if (s->early_data_state == SSL_EARLY_DATA_CONNECTING - && s->max_early_data > 0) { + && s->max_early_data > 0 + && (s->options & SSL_OP_ENABLE_MIDDLEBOX_COMPAT) == 0) { /* * We haven't selected TLSv1.3 yet so we don't call the change * cipher state function associated with the SSL_METHOD. Instead @@ -723,6 +730,18 @@ WORK_STATE ossl_statem_client_post_work(SSL *s, WORK_STATE wst) case TLS_ST_CW_CHANGE: if (SSL_IS_TLS13(s)) break; + if (s->early_data_state == SSL_EARLY_DATA_CONNECTING + && s->max_early_data > 0) { + /* + * We haven't selected TLSv1.3 yet so we don't call the change + * cipher state function associated with the SSL_METHOD. Instead + * we call tls13_change_cipher_state() directly. + */ + if (!tls13_change_cipher_state(s, + SSL3_CC_EARLY | SSL3_CHANGE_CIPHER_CLIENT_WRITE)) + return WORK_ERROR; + break; + } s->session->cipher = s->s3->tmp.new_cipher; #ifdef OPENSSL_NO_COMP s->session->compress_meth = 0; -- 2.25.1