diff -up openssl-1.0.1e/ssl/d1_both.c.dtls1-dos2 openssl-1.0.1e/ssl/d1_both.c
--- openssl-1.0.1e/ssl/d1_both.c.dtls1-dos2 2016-09-20 15:53:03.748445806 +0200
+++ openssl-1.0.1e/ssl/d1_both.c 2016-09-20 16:12:01.422861505 +0200
@@ -211,7 +211,7 @@ dtls1_hm_fragment_new(unsigned long frag
return frag;
}
-static void
+void
dtls1_hm_fragment_free(hm_fragment *frag)
{
@@ -544,11 +544,26 @@ dtls1_retrieve_buffered_fragment(SSL *s,
int al;
*ok = 0;
- item = pqueue_peek(s->d1->buffered_messages);
- if ( item == NULL)
- return 0;
+ do
+ {
+ item = pqueue_peek(s->d1->buffered_messages);
+ if (item == NULL)
+ return 0;
+
+ frag = (hm_fragment *)item->data;
+
+ if (frag->msg_header.seq < s->d1->handshake_read_seq)
+ {
+ /* This is a stale message that has been buffered so clear it */
+ pqueue_pop(s->d1->buffered_messages);
+ dtls1_hm_fragment_free(frag);
+ pitem_free(item);
+ item = NULL;
+ frag = NULL;
+ }
+ }
+ while (item == NULL);
- frag = (hm_fragment *)item->data;
/* Don't return if reassembly still in progress */
if (frag->reassembly != NULL)
@@ -1339,21 +1354,6 @@ dtls1_retransmit_message(SSL *s, unsigne
return ret;
}
-/* call this function when the buffered messages are no longer needed */
-void
-dtls1_clear_record_buffer(SSL *s)
- {
- pitem *item;
-
- for(item = pqueue_pop(s->d1->sent_messages);
- item != NULL; item = pqueue_pop(s->d1->sent_messages))
- {
- dtls1_hm_fragment_free((hm_fragment *)item->data);
- pitem_free(item);
- }
- }
-
-
unsigned char *
dtls1_set_message_header(SSL *s, unsigned char *p, unsigned char mt,
unsigned long len, unsigned long frag_off, unsigned long frag_len)
diff -up openssl-1.0.1e/ssl/d1_clnt.c.dtls1-dos2 openssl-1.0.1e/ssl/d1_clnt.c
--- openssl-1.0.1e/ssl/d1_clnt.c.dtls1-dos2 2016-09-20 15:53:03.748445806 +0200
+++ openssl-1.0.1e/ssl/d1_clnt.c 2016-09-20 15:58:38.292200957 +0200
@@ -739,6 +739,7 @@ int dtls1_connect(SSL *s)
/* done with handshaking */
s->d1->handshake_read_seq = 0;
s->d1->next_handshake_write_seq = 0;
+ dtls1_clear_received_buffer(s);
goto end;
/* break; */
diff -up openssl-1.0.1e/ssl/d1_lib.c.dtls1-dos2 openssl-1.0.1e/ssl/d1_lib.c
--- openssl-1.0.1e/ssl/d1_lib.c.dtls1-dos2 2016-09-20 15:53:03.749445830 +0200
+++ openssl-1.0.1e/ssl/d1_lib.c 2016-09-20 16:18:10.046443374 +0200
@@ -133,7 +133,6 @@ int dtls1_new(SSL *s)
static void dtls1_clear_queues(SSL *s)
{
pitem *item = NULL;
- hm_fragment *frag = NULL;
DTLS1_RECORD_DATA *rdata;
while( (item = pqueue_pop(s->d1->unprocessed_rcds.q)) != NULL)
@@ -158,32 +157,45 @@ static void dtls1_clear_queues(SSL *s)
pitem_free(item);
}
- while( (item = pqueue_pop(s->d1->buffered_messages)) != NULL)
- {
+ while ((item = pqueue_pop(s->d1->buffered_app_data.q)) != NULL)
+ {
+ rdata = (DTLS1_RECORD_DATA *)item->data;
+ if (rdata->rbuf.buf)
+ {
+ OPENSSL_free(rdata->rbuf.buf);
+ }
+ OPENSSL_free(item->data);
+ pitem_free(item);
+ }
+
+ dtls1_clear_received_buffer(s);
+ dtls1_clear_sent_buffer(s);
+ }
+
+void dtls1_clear_received_buffer(SSL *s)
+ {
+ pitem *item = NULL;
+ hm_fragment *frag = NULL;
+
+ while ((item = pqueue_pop(s->d1->buffered_messages)) != NULL)
+ {
frag = (hm_fragment *)item->data;
- OPENSSL_free(frag->fragment);
- OPENSSL_free(frag);
+ dtls1_hm_fragment_free(frag);
pitem_free(item);
}
+ }
- while ( (item = pqueue_pop(s->d1->sent_messages)) != NULL)
- {
+void dtls1_clear_sent_buffer(SSL *s)
+ {
+ pitem *item = NULL;
+ hm_fragment *frag = NULL;
+
+ while ((item = pqueue_pop(s->d1->sent_messages)) != NULL)
+ {
frag = (hm_fragment *)item->data;
- OPENSSL_free(frag->fragment);
- OPENSSL_free(frag);
+ dtls1_hm_fragment_free(frag);
pitem_free(item);
}
-
- while ( (item = pqueue_pop(s->d1->buffered_app_data.q)) != NULL)
- {
- rdata = (DTLS1_RECORD_DATA *) item->data;
- if (rdata->rbuf.buf)
- {
- OPENSSL_free(rdata->rbuf.buf);
- }
- OPENSSL_free(item->data);
- pitem_free(item);
- }
}
void dtls1_free(SSL *s)
@@ -410,7 +422,7 @@ void dtls1_stop_timer(SSL *s)
s->d1->timeout_duration = 1;
BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, &(s->d1->next_timeout));
/* Clear retransmission buffer */
- dtls1_clear_record_buffer(s);
+ dtls1_clear_sent_buffer(s);
}
int dtls1_check_timeout_num(SSL *s)
diff -up openssl-1.0.1e/ssl/d1_pkt.c.dtls1-dos2 openssl-1.0.1e/ssl/d1_pkt.c
--- openssl-1.0.1e/ssl/d1_pkt.c.dtls1-dos2 2016-09-20 15:53:17.246758715 +0200
+++ openssl-1.0.1e/ssl/d1_pkt.c 2016-09-20 16:14:33.020390824 +0200
@@ -1900,6 +1900,12 @@ dtls1_reset_seq_numbers(SSL *s, int rw)
s->d1->r_epoch++;
memcpy(&(s->d1->bitmap), &(s->d1->next_bitmap), sizeof(DTLS1_BITMAP));
memset(&(s->d1->next_bitmap), 0x00, sizeof(DTLS1_BITMAP));
+
+ /*
+ * We must not use any buffered messages received from the previous
+ * epoch
+ */
+ dtls1_clear_received_buffer(s);
}
else
{
diff -up openssl-1.0.1e/ssl/d1_srvr.c.dtls1-dos2 openssl-1.0.1e/ssl/d1_srvr.c
--- openssl-1.0.1e/ssl/d1_srvr.c.dtls1-dos2 2016-09-20 15:53:03.750445853 +0200
+++ openssl-1.0.1e/ssl/d1_srvr.c 2016-09-20 16:15:39.699943181 +0200
@@ -276,7 +276,7 @@ int dtls1_accept(SSL *s)
case SSL3_ST_SW_HELLO_REQ_B:
s->shutdown=0;
- dtls1_clear_record_buffer(s);
+ dtls1_clear_sent_buffer(s);
dtls1_start_timer(s);
ret=dtls1_send_hello_request(s);
if (ret <= 0) goto end;
@@ -811,6 +811,7 @@ int dtls1_accept(SSL *s)
/* next message is server hello */
s->d1->handshake_write_seq = 0;
s->d1->next_handshake_write_seq = 0;
+ dtls1_clear_received_buffer(s);
goto end;
/* break; */
diff -up openssl-1.0.1e/ssl/ssl_locl.h.dtls1-dos2 openssl-1.0.1e/ssl/ssl_locl.h
--- openssl-1.0.1e/ssl/ssl_locl.h.dtls1-dos2 2016-09-20 15:53:03.751445876 +0200
+++ openssl-1.0.1e/ssl/ssl_locl.h 2016-09-20 16:11:36.288276350 +0200
@@ -974,7 +974,8 @@ int dtls1_retransmit_message(SSL *s, uns
unsigned long frag_off, int *found);
int dtls1_get_queue_priority(unsigned short seq, int is_ccs);
int dtls1_retransmit_buffered_messages(SSL *s);
-void dtls1_clear_record_buffer(SSL *s);
+void dtls1_clear_received_buffer(SSL *s);
+void dtls1_clear_sent_buffer(SSL *s);
void dtls1_get_message_header(unsigned char *data, struct hm_header_st *msg_hdr);
void dtls1_get_ccs_header(unsigned char *data, struct ccs_header_st *ccs_hdr);
void dtls1_reset_seq_numbers(SSL *s, int rw);
@@ -989,6 +990,7 @@ int dtls1_is_timer_expired(SSL *s);
void dtls1_double_timeout(SSL *s);
int dtls1_send_newsession_ticket(SSL *s);
unsigned int dtls1_min_mtu(void);
+void dtls1_hm_fragment_free(hm_fragment *frag);
/* some client-only functions */
int ssl3_client_hello(SSL *s);