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;