The branch OpenSSL_1_0_2-stable has been updated
       via  22646a075e75991b4e8f5d67171e45a6aead5b48 (commit)
      from  006a788c84e541c8920dd2ad85fb62b52185c519 (commit)


- Log -----------------------------------------------------------------
commit 22646a075e75991b4e8f5d67171e45a6aead5b48
Author: Matt Caswell <m...@openssl.org>
Date:   Wed Sep 21 14:48:16 2016 +0100

    Don't allow too many consecutive warning alerts
    
    Certain warning alerts are ignored if they are received. This can mean that
    no progress will be made if one peer continually sends those warning alerts.
    Implement a count so that we abort the connection if we receive too many.
    
    Issue reported by Shi Lei.
    
    Reviewed-by: Rich Salz <rs...@openssl.org>

-----------------------------------------------------------------------

Summary of changes:
 ssl/d1_pkt.c   | 15 +++++++++++++++
 ssl/s3_pkt.c   | 15 +++++++++++++++
 ssl/ssl.h      |  1 +
 ssl/ssl_locl.h |  4 ++++
 4 files changed, 35 insertions(+)

diff --git a/ssl/d1_pkt.c b/ssl/d1_pkt.c
index df2e42e..7a02459 100644
--- a/ssl/d1_pkt.c
+++ b/ssl/d1_pkt.c
@@ -951,6 +951,13 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, 
int len, int peek)
         goto start;
     }
 
+    /*
+     * Reset the count of consecutive warning alerts if we've got a non-empty
+     * record that isn't an alert.
+     */
+    if (rr->type != SSL3_RT_ALERT && rr->length != 0)
+        s->cert->alert_count = 0;
+
     /* we now have a packet which can be read and processed */
 
     if (s->s3->change_cipher_spec /* set when we receive ChangeCipherSpec,
@@ -1217,6 +1224,14 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char 
*buf, int len, int peek)
 
         if (alert_level == SSL3_AL_WARNING) {
             s->s3->warn_alert = alert_descr;
+
+            s->cert->alert_count++;
+            if (s->cert->alert_count == MAX_WARN_ALERT_COUNT) {
+                al = SSL_AD_UNEXPECTED_MESSAGE;
+                SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_TOO_MANY_WARN_ALERTS);
+                goto f_err;
+            }
+
             if (alert_descr == SSL_AD_CLOSE_NOTIFY) {
 #ifndef OPENSSL_NO_SCTP
                 /*
diff --git a/ssl/s3_pkt.c b/ssl/s3_pkt.c
index df124cf..be37ef0 100644
--- a/ssl/s3_pkt.c
+++ b/ssl/s3_pkt.c
@@ -1229,6 +1229,13 @@ int ssl3_read_bytes(SSL *s, int type, unsigned char 
*buf, int len, int peek)
             return (ret);
     }
 
+    /*
+     * Reset the count of consecutive warning alerts if we've got a non-empty
+     * record that isn't an alert.
+     */
+    if (rr->type != SSL3_RT_ALERT && rr->length != 0)
+        s->cert->alert_count = 0;
+
     /* we now have a packet which can be read and processed */
 
     if (s->s3->change_cipher_spec /* set when we receive ChangeCipherSpec,
@@ -1443,6 +1450,14 @@ int ssl3_read_bytes(SSL *s, int type, unsigned char 
*buf, int len, int peek)
 
         if (alert_level == SSL3_AL_WARNING) {
             s->s3->warn_alert = alert_descr;
+
+            s->cert->alert_count++;
+            if (s->cert->alert_count == MAX_WARN_ALERT_COUNT) {
+                al = SSL_AD_UNEXPECTED_MESSAGE;
+                SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_TOO_MANY_WARN_ALERTS);
+                goto f_err;
+            }
+
             if (alert_descr == SSL_AD_CLOSE_NOTIFY) {
                 s->shutdown |= SSL_RECEIVED_SHUTDOWN;
                 return (0);
diff --git a/ssl/ssl.h b/ssl/ssl.h
index 2638755..90aeb0c 100644
--- a/ssl/ssl.h
+++ b/ssl/ssl.h
@@ -3107,6 +3107,7 @@ void ERR_load_SSL_strings(void);
 # define SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST             157
 # define SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST 233
 # define SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG    234
+# define SSL_R_TOO_MANY_WARN_ALERTS                       409
 # define SSL_R_TRIED_TO_USE_UNSUPPORTED_CIPHER            235
 # define SSL_R_UNABLE_TO_DECODE_DH_CERTS                  236
 # define SSL_R_UNABLE_TO_DECODE_ECDH_CERTS                313
diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h
index e358031..6df725f 100644
--- a/ssl/ssl_locl.h
+++ b/ssl/ssl_locl.h
@@ -591,6 +591,8 @@ typedef struct {
  */
 # define SSL_EXT_FLAG_SENT       0x2
 
+# define MAX_WARN_ALERT_COUNT    5
+
 typedef struct {
     custom_ext_method *meths;
     size_t meths_count;
@@ -698,6 +700,8 @@ typedef struct cert_st {
     unsigned char *alpn_proposed;   /* server */
     unsigned int alpn_proposed_len;
     int alpn_sent;                  /* client */
+    /* Count of the number of consecutive warning alerts received */
+    unsigned int alert_count;
 } CERT;
 
 typedef struct sess_cert_st {
_____
openssl-commits mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-commits

Reply via email to