Add the ability for a client to receive a KeyUpdate message
authorMatt Caswell <matt@openssl.org>
Thu, 9 Feb 2017 12:07:31 +0000 (12:07 +0000)
committerMatt Caswell <matt@openssl.org>
Fri, 17 Feb 2017 10:28:00 +0000 (10:28 +0000)
This just receives the message. It doesn't actually update any keys yet.

Reviewed-by: Rich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/2609)

include/openssl/ssl.h
ssl/ssl_err.c
ssl/statem/statem_clnt.c
ssl/statem/statem_lib.c
ssl/statem/statem_locl.h

index 88d7736..ba98a9f 100644 (file)
@@ -892,7 +892,9 @@ typedef enum {
     TLS_ST_SW_HELLO_RETRY_REQUEST,
     TLS_ST_CR_HELLO_RETRY_REQUEST,
     TLS_ST_SW_KEY_UPDATE,
-    TLS_ST_CW_KEY_UPDATE
+    TLS_ST_CW_KEY_UPDATE,
+    TLS_ST_SR_KEY_UPDATE,
+    TLS_ST_CR_KEY_UPDATE
 } OSSL_HANDSHAKE_STATE;
 
 /*
@@ -2375,6 +2377,7 @@ int ERR_load_SSL_strings(void);
 # define SSL_F_TLS_PROCESS_HELLO_RETRY_REQUEST            511
 # define SSL_F_TLS_PROCESS_INITIAL_SERVER_FLIGHT          442
 # define SSL_F_TLS_PROCESS_KEY_EXCHANGE                   365
+# define SSL_F_TLS_PROCESS_KEY_UPDATE                     513
 # define SSL_F_TLS_PROCESS_NEW_SESSION_TICKET             366
 # define SSL_F_TLS_PROCESS_NEXT_PROTO                     383
 # define SSL_F_TLS_PROCESS_SERVER_CERTIFICATE             367
@@ -2406,6 +2409,7 @@ int ERR_load_SSL_strings(void);
 # define SSL_R_BAD_HANDSHAKE_LENGTH                       332
 # define SSL_R_BAD_HELLO_REQUEST                          105
 # define SSL_R_BAD_KEY_SHARE                              108
+# define SSL_R_BAD_KEY_UPDATE                             122
 # define SSL_R_BAD_LENGTH                                 271
 # define SSL_R_BAD_PACKET_LENGTH                          115
 # define SSL_R_BAD_PROTOCOL_VERSION_NUMBER                116
index 2d9efbb..2a8cd0a 100644 (file)
@@ -422,6 +422,7 @@ static ERR_STRING_DATA SSL_str_functs[] = {
     {ERR_FUNC(SSL_F_TLS_PROCESS_INITIAL_SERVER_FLIGHT),
      "tls_process_initial_server_flight"},
     {ERR_FUNC(SSL_F_TLS_PROCESS_KEY_EXCHANGE), "tls_process_key_exchange"},
+    {ERR_FUNC(SSL_F_TLS_PROCESS_KEY_UPDATE), "tls_process_key_update"},
     {ERR_FUNC(SSL_F_TLS_PROCESS_NEW_SESSION_TICKET),
      "tls_process_new_session_ticket"},
     {ERR_FUNC(SSL_F_TLS_PROCESS_NEXT_PROTO), "tls_process_next_proto"},
@@ -464,6 +465,7 @@ static ERR_STRING_DATA SSL_str_reasons[] = {
     {ERR_REASON(SSL_R_BAD_HANDSHAKE_LENGTH), "bad handshake length"},
     {ERR_REASON(SSL_R_BAD_HELLO_REQUEST), "bad hello request"},
     {ERR_REASON(SSL_R_BAD_KEY_SHARE), "bad key share"},
+    {ERR_REASON(SSL_R_BAD_KEY_UPDATE), "bad key update"},
     {ERR_REASON(SSL_R_BAD_LENGTH), "bad length"},
     {ERR_REASON(SSL_R_BAD_PACKET_LENGTH), "bad packet length"},
     {ERR_REASON(SSL_R_BAD_PROTOCOL_VERSION_NUMBER),
index 4923e24..79bf200 100644 (file)
@@ -200,6 +200,10 @@ static int ossl_statem_client13_read_transition(SSL *s, int mt)
             st->hand_state = TLS_ST_CR_SESSION_TICKET;
             return 1;
         }
+        if (mt == SSL3_MT_KEY_UPDATE) {
+            st->hand_state = TLS_ST_CR_KEY_UPDATE;
+            return 1;
+        }
         break;
     }
 
@@ -439,6 +443,7 @@ static WRITE_TRAN ossl_statem_client13_write_transition(SSL *s)
         st->hand_state = TLS_ST_CW_FINISHED;
         return WRITE_TRAN_CONTINUE;
 
+    case TLS_ST_CR_KEY_UPDATE:
     case TLS_ST_CR_SESSION_TICKET:
     case TLS_ST_CW_FINISHED:
         st->hand_state = TLS_ST_OK;
@@ -843,6 +848,9 @@ size_t ossl_statem_client_max_message_size(SSL *s)
 
     case TLS_ST_CR_ENCRYPTED_EXTENSIONS:
         return ENCRYPTED_EXTENSIONS_MAX_LENGTH;
+
+    case TLS_ST_CR_KEY_UPDATE:
+        return KEY_UPDATE_MAX_LENGTH;
     }
 }
 
@@ -899,6 +907,9 @@ MSG_PROCESS_RETURN ossl_statem_client_process_message(SSL *s, PACKET *pkt)
 
     case TLS_ST_CR_ENCRYPTED_EXTENSIONS:
         return tls_process_encrypted_extensions(s, pkt);
+
+    case TLS_ST_CR_KEY_UPDATE:
+        return tls_process_key_update(s, pkt);
     }
 }
 
index fa7387a..72cb7f2 100644 (file)
@@ -508,6 +508,24 @@ int tls_construct_key_update(SSL *s, WPACKET *pkt)
     return 0;
 }
 
+
+MSG_PROCESS_RETURN tls_process_key_update(SSL *s, PACKET *pkt)
+{
+    unsigned int updatetype;
+
+    if (!PACKET_get_1(pkt, &updatetype)
+            || PACKET_remaining(pkt) != 0
+            || (updatetype != SSL_KEY_UPDATE_NOT_REQUESTED
+                && updatetype != SSL_KEY_UPDATE_REQUESTED)) {
+        ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+        SSLerr(SSL_F_TLS_PROCESS_KEY_UPDATE, SSL_R_BAD_KEY_UPDATE);
+        ossl_statem_set_error(s);
+        return MSG_PROCESS_ERROR;
+    }
+
+    return MSG_PROCESS_FINISHED_READING;
+}
+
 #ifndef OPENSSL_NO_NEXTPROTONEG
 /*
  * ssl3_take_mac calculates the Finished MAC for the handshakes messages seen
index 96ddac2..6713dad 100644 (file)
@@ -23,6 +23,7 @@
 #define ENCRYPTED_EXTENSIONS_MAX_LENGTH 20000
 #define SERVER_KEY_EXCH_MAX_LENGTH      102400
 #define SERVER_HELLO_DONE_MAX_LENGTH    0
+#define KEY_UPDATE_MAX_LENGTH           1
 #define CCS_MAX_LENGTH                  1
 /* Max should actually be 36 but we are generous */
 #define FINISHED_MAX_LENGTH             64
@@ -112,6 +113,7 @@ __owur int dtls_construct_change_cipher_spec(SSL *s, WPACKET *pkt);
 
 __owur int tls_construct_finished(SSL *s, WPACKET *pkt);
 __owur int tls_construct_key_update(SSL *s, WPACKET *pkt);
+__owur MSG_PROCESS_RETURN tls_process_key_update(SSL *s, PACKET *pkt);
 __owur WORK_STATE tls_finish_handshake(SSL *s, WORK_STATE wst, int clearbufs);
 __owur WORK_STATE dtls_wait_for_dry(SSL *s);