diff -up openssl-1.0.1e/ssl/d1_pkt.c.many-alerts openssl-1.0.1e/ssl/d1_pkt.c --- openssl-1.0.1e/ssl/d1_pkt.c.many-alerts 2016-10-04 16:12:30.000000000 +0200 +++ openssl-1.0.1e/ssl/d1_pkt.c 2016-11-01 10:48:05.270349440 +0100 @@ -915,6 +915,13 @@ start: 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, @@ -1184,6 +1191,15 @@ start: if (alert_level == 1) /* 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 -up openssl-1.0.1e/ssl/ssl_err.c.many-alerts openssl-1.0.1e/ssl/ssl_err.c --- openssl-1.0.1e/ssl/ssl_err.c.many-alerts 2016-10-04 16:12:30.000000000 +0200 +++ openssl-1.0.1e/ssl/ssl_err.c 2016-11-01 10:54:04.673900027 +0100 @@ -552,6 +552,7 @@ static ERR_STRING_DATA SSL_str_reasons[] {ERR_REASON(SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST),"tls invalid ecpointformat list"}, {ERR_REASON(SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST),"tls peer did not respond with certificate list"}, {ERR_REASON(SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG),"tls rsa encrypted value length is wrong"}, +{ERR_REASON(SSL_R_TOO_MANY_WARN_ALERTS), "too many warn alerts"}, {ERR_REASON(SSL_R_TRIED_TO_USE_UNSUPPORTED_CIPHER),"tried to use unsupported cipher"}, {ERR_REASON(SSL_R_UNABLE_TO_DECODE_DH_CERTS),"unable to decode dh certs"}, {ERR_REASON(SSL_R_UNABLE_TO_DECODE_ECDH_CERTS),"unable to decode ecdh certs"}, diff -up openssl-1.0.1e/ssl/ssl.h.many-alerts openssl-1.0.1e/ssl/ssl.h --- openssl-1.0.1e/ssl/ssl.h.many-alerts 2016-10-04 16:12:30.000000000 +0200 +++ openssl-1.0.1e/ssl/ssl.h 2016-11-01 10:52:48.442086392 +0100 @@ -2474,6 +2474,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 -up openssl-1.0.1e/ssl/ssl_locl.h.many-alerts openssl-1.0.1e/ssl/ssl_locl.h --- openssl-1.0.1e/ssl/ssl_locl.h.many-alerts 2016-10-04 16:12:30.000000000 +0200 +++ openssl-1.0.1e/ssl/ssl_locl.h 2016-11-01 10:55:39.171148215 +0100 @@ -485,6 +485,8 @@ typedef struct cert_pkey_st const EVP_MD *digest; } CERT_PKEY; +# define MAX_WARN_ALERT_COUNT 5 + typedef struct cert_st { /* Current active set */ @@ -516,6 +518,7 @@ typedef struct cert_st CERT_PKEY pkeys[SSL_PKEY_NUM]; int references; /* >1 only if SSL_copy_session_id is used */ + unsigned int alert_count; } CERT; diff -up openssl-1.0.1e/ssl/s3_pkt.c.many-alerts openssl-1.0.1e/ssl/s3_pkt.c --- openssl-1.0.1e/ssl/s3_pkt.c.many-alerts 2016-10-04 16:12:30.000000000 +0200 +++ openssl-1.0.1e/ssl/s3_pkt.c 2016-11-01 10:51:21.504018044 +0100 @@ -1009,6 +1009,13 @@ start: if (ret <= 0) 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, @@ -1225,6 +1232,15 @@ start: if (alert_level == 1) /* 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;