diff options
author | Matt Caswell <matt@openssl.org> | 2017-02-13 11:55:38 +0000 |
---|---|---|
committer | Matt Caswell <matt@openssl.org> | 2017-02-17 10:28:00 +0000 |
commit | 82f992cbe0db628879aae4bf3ddd95cfcb1098a5 (patch) | |
tree | d2d18ff28dbe453e55ac3378e059cb53a1d7090c | |
parent | 57389a3261075cc1266218742434aa749cf3733e (diff) | |
download | openssl-82f992cbe0db628879aae4bf3ddd95cfcb1098a5.tar.gz |
Limit the number of KeyUpdate messages we can process
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)
-rw-r--r-- | include/openssl/ssl.h | 1 | ||||
-rw-r--r-- | ssl/ssl_err.c | 1 | ||||
-rw-r--r-- | ssl/ssl_locl.h | 4 | ||||
-rw-r--r-- | ssl/statem/statem_lib.c | 8 |
4 files changed, 14 insertions, 0 deletions
diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h index 72f835460a..da5d1d09d2 100644 --- a/include/openssl/ssl.h +++ b/include/openssl/ssl.h @@ -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 diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c index ec2b41dabf..341712cdb7 100644 --- a/ssl/ssl_err.c +++ b/ssl/ssl_err.c @@ -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"}, diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h index 12eba2130e..31afe10f10 100644 --- a/ssl/ssl_locl.h +++ b/ssl/ssl_locl.h @@ -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 */ diff --git a/ssl/statem/statem_lib.c b/ssl/statem/statem_lib.c index 809fe6fd50..5e194e886a 100644 --- a/ssl/statem/statem_lib.c +++ b/ssl/statem/statem_lib.c @@ -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 |