Add the ability for a client to send a KeyUpdate message

Reviewed-by: Rich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/2609)
diff --git a/ssl/statem/statem_clnt.c b/ssl/statem/statem_clnt.c
index 79bf200..ced3317 100644
--- a/ssl/statem/statem_clnt.c
+++ b/ssl/statem/statem_clnt.c
@@ -406,11 +406,6 @@
     OSSL_STATEM *st = &s->statem;
 
     /*
-     * TODO(TLS1.3): This is still based on the TLSv1.2 state machine. Over time
-     * we will update this to look more like real TLSv1.3
-     */
-
-    /*
      * Note: There are no cases for TLS_ST_BEFORE because we haven't negotiated
      * TLSv1.3 yet at that point. They are handled by
      * ossl_statem_client_write_transition().
@@ -444,6 +439,7 @@
         return WRITE_TRAN_CONTINUE;
 
     case TLS_ST_CR_KEY_UPDATE:
+    case TLS_ST_CW_KEY_UPDATE:
     case TLS_ST_CR_SESSION_TICKET:
     case TLS_ST_CW_FINISHED:
         st->hand_state = TLS_ST_OK;
@@ -451,7 +447,12 @@
         return WRITE_TRAN_CONTINUE;
 
     case TLS_ST_OK:
-        /* Just go straight to trying to read from the server */
+        if (s->key_update != SSL_KEY_UPDATE_NONE) {
+            st->hand_state = TLS_ST_CW_KEY_UPDATE;
+            return WRITE_TRAN_CONTINUE;
+        }
+
+        /* Try to read from the server instead */
         return WRITE_TRAN_FINISHED;
     }
 }
@@ -724,6 +725,11 @@
             return WORK_ERROR;
         }
         break;
+
+    case TLS_ST_CW_KEY_UPDATE:
+        if (statem_flush(s) != 1)
+            return WORK_MORE_A;
+        break;
     }
 
     return WORK_FINISHED_CONTINUE;
@@ -785,6 +791,11 @@
         *confunc = tls_construct_finished;
         *mt = SSL3_MT_FINISHED;
         break;
+
+    case TLS_ST_CW_KEY_UPDATE:
+        *confunc = tls_construct_key_update;
+        *mt = SSL3_MT_KEY_UPDATE;
+        break;
     }
 
     return 1;