From 4d02f8706381bf2bd002951daef9b26d9ed85968 Mon Sep 17 00:00:00 2001
From: Matt Caswell <matt@openssl.org>
Date: Wed, 8 Nov 2017 11:37:12 +0000
Subject: [PATCH] Send a CCS from the client in a non-early_data handshake

Reviewed-by: Ben Kaduk <kaduk@mit.edu>
(Merged from https://github.com/openssl/openssl/pull/4701)
---
 ssl/statem/statem_clnt.c     |  6 ++++++
 util/perl/TLSProxy/Record.pm | 24 +++++++++++++-----------
 2 files changed, 19 insertions(+), 11 deletions(-)

diff --git a/ssl/statem/statem_clnt.c b/ssl/statem/statem_clnt.c
index 99ebe22512..91fb13d805 100644
--- a/ssl/statem/statem_clnt.c
+++ b/ssl/statem/statem_clnt.c
@@ -395,6 +395,9 @@ static WRITE_TRAN ossl_statem_client13_write_transition(SSL *s)
         if (s->early_data_state == SSL_EARLY_DATA_WRITE_RETRY
                 || s->early_data_state == SSL_EARLY_DATA_FINISHED_WRITING)
             st->hand_state = TLS_ST_PENDING_EARLY_DATA_END;
+        else if ((s->options & SSL_OP_ENABLE_MIDDLEBOX_COMPAT) != 0
+                    && !s->hello_retry_request)
+            st->hand_state = TLS_ST_CW_CHANGE;
         else
             st->hand_state = (s->s3->tmp.cert_req != 0) ? TLS_ST_CW_CERT
                                                         : TLS_ST_CW_FINISHED;
@@ -408,6 +411,7 @@ static WRITE_TRAN ossl_statem_client13_write_transition(SSL *s)
         /* Fall through */
 
     case TLS_ST_CW_END_OF_EARLY_DATA:
+    case TLS_ST_CW_CHANGE:
         st->hand_state = (s->s3->tmp.cert_req != 0) ? TLS_ST_CW_CERT
                                                     : TLS_ST_CW_FINISHED;
         return WRITE_TRAN_CONTINUE;
@@ -717,6 +721,8 @@ WORK_STATE ossl_statem_client_post_work(SSL *s, WORK_STATE wst)
         break;
 
     case TLS_ST_CW_CHANGE:
+        if (SSL_IS_TLS13(s))
+            break;
         s->session->cipher = s->s3->tmp.new_cipher;
 #ifdef OPENSSL_NO_COMP
         s->session->compress_meth = 0;
diff --git a/util/perl/TLSProxy/Record.pm b/util/perl/TLSProxy/Record.pm
index c5583082da..b2a1e166c9 100644
--- a/util/perl/TLSProxy/Record.pm
+++ b/util/perl/TLSProxy/Record.pm
@@ -109,19 +109,21 @@ sub get_records
                 substr($packet, TLS_RECORD_HEADER_LENGTH, $len_real)
             );
 
-            if (($server && $server_encrypting)
-                     || (!$server && $client_encrypting)) {
-                if (!TLSProxy::Proxy->is_tls13() && $etm) {
-                    $record->decryptETM();
-                } else {
-                    $record->decrypt();
+            if (!TLSProxy::Proxy->is_tls13() || $content_type != RT_CCS) {
+                if (($server && $server_encrypting)
+                         || (!$server && $client_encrypting)) {
+                    if (!TLSProxy::Proxy->is_tls13() && $etm) {
+                        $record->decryptETM();
+                    } else {
+                        $record->decrypt();
+                    }
+                    $record->encrypted(1);
                 }
-                $record->encrypted(1);
-            }
 
-            if (TLSProxy::Proxy->is_tls13()) {
-                print "  Inner content type: "
-                      .$record_type{$record->content_type()}."\n";
+                if (TLSProxy::Proxy->is_tls13()) {
+                    print "  Inner content type: "
+                          .$record_type{$record->content_type()}."\n";
+                }
             }
 
             push @record_list, $record;
-- 
2.25.1