Limit the number of KeyUpdate messages we can process
authorMatt Caswell <matt@openssl.org>
Mon, 13 Feb 2017 11:55:38 +0000 (11:55 +0000)
committerMatt Caswell <matt@openssl.org>
Fri, 17 Feb 2017 10:28:00 +0000 (10:28 +0000)
Too many KeyUpdate message could be inicative of a problem (e.g. an
infinite KeyUpdate loop if the peer always responds to a KeyUpdate message
with an "update_requested" KeyUpdate response), or (conceivably) an attack.
Either way we limit the number of KeyUpdate messages we are prepared to
handle.

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/ssl_locl.h
ssl/statem/statem_lib.c

index 72f8354..da5d1d0 100644 (file)
@@ -2622,6 +2622,7 @@ int ERR_load_SSL_strings(void);
 # define SSL_R_TLS_HEARTBEAT_PENDING                      366
 # define SSL_R_TLS_ILLEGAL_EXPORTER_LABEL                 367
 # define SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST             157
+# define SSL_R_TOO_MANY_KEY_UPDATES                       132
 # define SSL_R_TOO_MANY_WARN_ALERTS                       409
 # define SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS             314
 # define SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS       239
index ec2b41d..341712c 100644 (file)
@@ -764,6 +764,7 @@ static ERR_STRING_DATA SSL_str_reasons[] = {
      "tls illegal exporter label"},
     {ERR_REASON(SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST),
      "tls invalid ecpointformat list"},
+    {ERR_REASON(SSL_R_TOO_MANY_KEY_UPDATES), "too many key updates"},
     {ERR_REASON(SSL_R_TOO_MANY_WARN_ALERTS), "too many warn alerts"},
     {ERR_REASON(SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS),
      "unable to find ecdh parameters"},
index 12eba21..31afe10 100644 (file)
@@ -996,6 +996,10 @@ struct ssl_st {
     EVP_CIPHER_CTX *enc_write_ctx; /* cryptographic state */
     unsigned char write_iv[EVP_MAX_IV_LENGTH]; /* TLSv1.3 static write IV */
     EVP_MD_CTX *write_hash;     /* used for mac generation */
+
+    /* Count of how many KeyUpdate messages we have received */
+    unsigned int key_update_count;
+
     /* session info */
     /* client cert? */
     /* This is used to hold the server certificate used */
index 809fe6f..5e194e8 100644 (file)
@@ -510,12 +510,20 @@ int tls_construct_key_update(SSL *s, WPACKET *pkt)
     return 0;
 }
 
+#define MAX_KEY_UPDATE_MESSAGES     32
 
 MSG_PROCESS_RETURN tls_process_key_update(SSL *s, PACKET *pkt)
 {
     int al;
     unsigned int updatetype;
 
+    s->key_update_count++;
+    if (s->key_update_count > MAX_KEY_UPDATE_MESSAGES) {
+        al = SSL_AD_ILLEGAL_PARAMETER;
+        SSLerr(SSL_F_TLS_PROCESS_KEY_UPDATE, SSL_R_TOO_MANY_KEY_UPDATES);
+        goto err;
+    }
+
     if (!PACKET_get_1(pkt, &updatetype)
             || PACKET_remaining(pkt) != 0
             || (updatetype != SSL_KEY_UPDATE_NOT_REQUESTED