Blob Blame History Raw
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;