Blame SOURCES/openssl-1.0.1e-cve-2016-2181.patch

653b37
diff -up openssl-1.0.1e/ssl/d1_pkt.c.dtls1-replay openssl-1.0.1e/ssl/d1_pkt.c
653b37
--- openssl-1.0.1e/ssl/d1_pkt.c.dtls1-replay	2016-09-20 16:29:36.767447143 +0200
653b37
+++ openssl-1.0.1e/ssl/d1_pkt.c	2016-09-20 16:44:56.654893514 +0200
653b37
@@ -178,7 +178,7 @@ static int dtls1_record_needs_buffering(
653b37
 #endif
653b37
 static int dtls1_buffer_record(SSL *s, record_pqueue *q,
653b37
 	unsigned char *priority);
653b37
-static int dtls1_process_record(SSL *s);
653b37
+static int dtls1_process_record(SSL *s, DTLS1_BITMAP *bitmap);
653b37
 
653b37
 /* copy buffered record into SSL structure */
653b37
 static int
653b37
@@ -304,32 +304,84 @@ static int
653b37
 dtls1_process_buffered_records(SSL *s)
653b37
     {
653b37
     pitem *item;
653b37
-    
653b37
+    SSL3_BUFFER *rb;
653b37
+    SSL3_RECORD *rr;
653b37
+    DTLS1_BITMAP *bitmap;
653b37
+    unsigned int is_next_epoch;
653b37
+    int replayok = 1;
653b37
+
653b37
     item = pqueue_peek(s->d1->unprocessed_rcds.q);
653b37
     if (item)
653b37
         {
653b37
         /* Check if epoch is current. */
653b37
         if (s->d1->unprocessed_rcds.epoch != s->d1->r_epoch)
653b37
-            return(1);  /* Nothing to do. */
653b37
-        
653b37
+            return 1;         /* Nothing to do. */
653b37
+
653b37
+        rr = &s->s3->rrec;
653b37
+        rb = &s->s3->rbuf;
653b37
+
653b37
+        if (rb->left > 0)
653b37
+	    {
653b37
+            /*
653b37
+             * We've still got data from the current packet to read. There could
653b37
+             * be a record from the new epoch in it - so don't overwrite it
653b37
+             * with the unprocessed records yet (we'll do it when we've
653b37
+             * finished reading the current packet).
653b37
+             */
653b37
+	    return 1;
653b37
+	    }
653b37
+
653b37
+
653b37
         /* Process all the records. */
653b37
         while (pqueue_peek(s->d1->unprocessed_rcds.q))
653b37
             {
653b37
             dtls1_get_unprocessed_record(s);
653b37
-            if ( ! dtls1_process_record(s))
653b37
-                return(0);
653b37
-            if(dtls1_buffer_record(s, &(s->d1->processed_rcds),
653b37
-                s->s3->rrec.seq_num)<0)
653b37
-                return -1;
653b37
-            }
653b37
+            bitmap = dtls1_get_bitmap(s, rr, &is_next_epoch);
653b37
+	    if (bitmap == NULL)
653b37
+		{
653b37
+                /*
653b37
+                 * Should not happen. This will only ever be NULL when the
653b37
+                 * current record is from a different epoch. But that cannot
653b37
+                 * be the case because we already checked the epoch above
653b37
+                 */
653b37
+                SSLerr(SSL_F_DTLS1_PROCESS_BUFFERED_RECORDS,
653b37
+                        ERR_R_INTERNAL_ERROR);
653b37
+                return 0;
653b37
+		}
653b37
+#ifndef OPENSSL_NO_SCTP
653b37
+	    /* Only do replay check if no SCTP bio */
653b37
+	    if (!BIO_dgram_is_sctp(SSL_get_rbio(s)))
653b37
+#endif
653b37
+		{
653b37
+                /*
653b37
+                 * Check whether this is a repeat, or aged record. We did this
653b37
+                 * check once already when we first received the record - but
653b37
+                 * we might have updated the window since then due to
653b37
+                 * records we subsequently processed.
653b37
+                 */
653b37
+                replayok = dtls1_record_replay_check(s, bitmap);
653b37
+		}
653b37
+
653b37
+            if (!replayok || !dtls1_process_record(s, bitmap))
653b37
+		{
653b37
+                /* dump this record */
653b37
+                rr->length = 0;
653b37
+                s->packet_length = 0;
653b37
+                continue;
653b37
+		}
653b37
+
653b37
+            if (dtls1_buffer_record(s, &(s->d1->processed_rcds),
653b37
+                                    s->s3->rrec.seq_num) < 0)
653b37
+                return 0;
653b37
         }
653b37
+    }
653b37
 
653b37
     /* sync epoch numbers once all the unprocessed records 
653b37
      * have been processed */
653b37
     s->d1->processed_rcds.epoch = s->d1->r_epoch;
653b37
     s->d1->unprocessed_rcds.epoch = s->d1->r_epoch + 1;
653b37
 
653b37
-    return(1);
653b37
+    return 1;
653b37
     }
653b37
 
653b37
 
653b37
@@ -379,7 +431,7 @@ dtls1_get_buffered_record(SSL *s)
653b37
 #endif
653b37
 
653b37
 static int
653b37
-dtls1_process_record(SSL *s)
653b37
+dtls1_process_record(SSL *s, DTLS1_BITMAP *bitmap)
653b37
 {
653b37
 	int i,al;
653b37
 	int enc_err;
653b37
@@ -535,6 +587,10 @@ printf("\n");
653b37
 
653b37
 	/* we have pulled in a full packet so zero things */
653b37
 	s->packet_length=0;
653b37
+
653b37
+	/* Mark receipt of record. */
653b37
+	dtls1_record_bitmap_update(s, bitmap);
653b37
+
653b37
 	return(1);
653b37
 
653b37
 f_err:
653b37
@@ -565,9 +621,10 @@ int dtls1_get_record(SSL *s)
653b37
 
653b37
 	rr= &(s->s3->rrec);
653b37
 
653b37
+again:
653b37
 	/* The epoch may have changed.  If so, process all the
653b37
 	 * pending records.  This is a non-blocking operation. */
653b37
-	if(dtls1_process_buffered_records(s)<0)
653b37
+	if(!dtls1_process_buffered_records(s))
653b37
 		return -1;
653b37
 
653b37
 	/* if we're renegotiating, then there may be buffered records */
653b37
@@ -575,7 +632,6 @@ int dtls1_get_record(SSL *s)
653b37
 		return 1;
653b37
 
653b37
 	/* get something from the wire */
653b37
-again:
653b37
 	/* check if we have the header */
653b37
 	if (	(s->rstate != SSL_ST_READ_BODY) ||
653b37
 		(s->packet_length < DTLS1_RT_HEADER_LENGTH)) 
653b37
@@ -707,20 +763,18 @@ again:
653b37
 			{
653b37
 			if(dtls1_buffer_record(s, &(s->d1->unprocessed_rcds), rr->seq_num)<0)
653b37
 				return -1;
653b37
-			dtls1_record_bitmap_update(s, bitmap);/* Mark receipt of record. */
653b37
 			}
653b37
 		rr->length = 0;
653b37
 		s->packet_length = 0;
653b37
 		goto again;
653b37
 		}
653b37
 
653b37
-	if (!dtls1_process_record(s))
653b37
+	if (!dtls1_process_record(s, bitmap))
653b37
 		{
653b37
 		rr->length = 0;
653b37
 		s->packet_length = 0;  /* dump this record */
653b37
 		goto again;   /* get another record */
653b37
 		}
653b37
-	dtls1_record_bitmap_update(s, bitmap);/* Mark receipt of record. */
653b37
 
653b37
 	return(1);
653b37
 
653b37
@@ -1811,8 +1865,13 @@ dtls1_get_bitmap(SSL *s, SSL3_RECORD *rr
653b37
     if (rr->epoch == s->d1->r_epoch)
653b37
         return &s->d1->bitmap;
653b37
 
653b37
-    /* Only HM and ALERT messages can be from the next epoch */
653b37
+    /*
653b37
+     * Only HM and ALERT messages can be from the next epoch and only if we
653b37
+     * have already processed all of the unprocessed records from the last
653b37
+     * epoch
653b37
+     */
653b37
     else if (rr->epoch == (unsigned long)(s->d1->r_epoch + 1) &&
653b37
+             s->d1->unprocessed_rcds.epoch != s->d1->r_epoch &&
653b37
         (rr->type == SSL3_RT_HANDSHAKE ||
653b37
             rr->type == SSL3_RT_ALERT))
653b37
         {
653b37
diff -up openssl-1.0.1e/ssl/ssl_err.c.dtls1-replay openssl-1.0.1e/ssl/ssl_err.c
653b37
--- openssl-1.0.1e/ssl/ssl_err.c.dtls1-replay	2016-09-20 14:55:57.789311197 +0200
653b37
+++ openssl-1.0.1e/ssl/ssl_err.c	2016-09-20 16:45:49.827132881 +0200
653b37
@@ -1,6 +1,6 @@
653b37
 /* ssl/ssl_err.c */
653b37
 /* ====================================================================
653b37
- * Copyright (c) 1999-2011 The OpenSSL Project.  All rights reserved.
653b37
+ * Copyright (c) 1999-2016 The OpenSSL Project.  All rights reserved.
653b37
  *
653b37
  * Redistribution and use in source and binary forms, with or without
653b37
  * modification, are permitted provided that the following conditions
653b37
@@ -92,6 +92,7 @@ static ERR_STRING_DATA SSL_str_functs[]=
653b37
 {ERR_FUNC(SSL_F_DTLS1_HEARTBEAT),	"DTLS1_HEARTBEAT"},
653b37
 {ERR_FUNC(SSL_F_DTLS1_OUTPUT_CERT_CHAIN),	"DTLS1_OUTPUT_CERT_CHAIN"},
653b37
 {ERR_FUNC(SSL_F_DTLS1_PREPROCESS_FRAGMENT),	"DTLS1_PREPROCESS_FRAGMENT"},
653b37
+{ERR_FUNC(SSL_F_DTLS1_PROCESS_BUFFERED_RECORDS),	"DTLS1_PROCESS_BUFFERED_RECORDS"},
653b37
 {ERR_FUNC(SSL_F_DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE),	"DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE"},
653b37
 {ERR_FUNC(SSL_F_DTLS1_PROCESS_RECORD),	"DTLS1_PROCESS_RECORD"},
653b37
 {ERR_FUNC(SSL_F_DTLS1_READ_BYTES),	"DTLS1_READ_BYTES"},
653b37
diff -up openssl-1.0.1e/ssl/ssl.h.dtls1-replay openssl-1.0.1e/ssl/ssl.h
653b37
--- openssl-1.0.1e/ssl/ssl.h.dtls1-replay	2016-09-20 16:29:36.768447167 +0200
653b37
+++ openssl-1.0.1e/ssl/ssl.h	2016-09-20 16:30:42.981991082 +0200
653b37
@@ -2023,6 +2023,7 @@ void ERR_load_SSL_strings(void);
653b37
 #define SSL_F_DTLS1_HEARTBEAT				 305
653b37
 #define SSL_F_DTLS1_OUTPUT_CERT_CHAIN			 255
653b37
 #define SSL_F_DTLS1_PREPROCESS_FRAGMENT			 288
653b37
+#define SSL_F_DTLS1_PROCESS_BUFFERED_RECORDS		 424
653b37
 #define SSL_F_DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE		 256
653b37
 #define SSL_F_DTLS1_PROCESS_RECORD			 257
653b37
 #define SSL_F_DTLS1_READ_BYTES				 258