Add the ability for a client to send a KeyUpdate message
authorMatt Caswell <matt@openssl.org>
Thu, 9 Feb 2017 13:12:00 +0000 (13:12 +0000)
committerMatt Caswell <matt@openssl.org>
Fri, 17 Feb 2017 10:28:00 +0000 (10:28 +0000)
Reviewed-by: Rich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/2609)

ssl/statem/statem_clnt.c
ssl/statem/statem_lib.c

index 79bf20029cdafe091c87509f671f032e22da0a56..ced331758d11d397195c3968b7bc8db578d0998e 100644 (file)
@@ -405,11 +405,6 @@ static WRITE_TRAN ossl_statem_client13_write_transition(SSL *s)
 {
     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
@@ -444,6 +439,7 @@ static WRITE_TRAN ossl_statem_client13_write_transition(SSL *s)
         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 @@ static WRITE_TRAN ossl_statem_client13_write_transition(SSL *s)
         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 @@ WORK_STATE ossl_statem_client_post_work(SSL *s, WORK_STATE wst)
             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 @@ int ossl_statem_client_construct_message(SSL *s, WPACKET *pkt,
         *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;
index 72cb7f2cc92a5a1809aa17103432b66bfe40abfd..6261804129f822c3c4bbb1d33f9eec0aac32335c 100644 (file)
@@ -502,6 +502,8 @@ int tls_construct_key_update(SSL *s, WPACKET *pkt)
         goto err;
     }
 
+    s->key_update = SSL_KEY_UPDATE_NONE;
+
     return 1;
  err:
     ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);