Commit 6252f3bc authored by Dr. Stephen Henson's avatar Dr. Stephen Henson
Browse files

PR: 1827

Submitted by: Robin Seggelmann <seggelmann@fh-muenster.de>
Approved by: steve@openssl.org

Fix application data in handshake bug.
parent 4e319926
Loading
Loading
Loading
Loading
+12 −1
Original line number Diff line number Diff line
@@ -114,6 +114,7 @@ int dtls1_new(SSL *s)
	d1->processed_rcds.q=pqueue_new();
	d1->buffered_messages = pqueue_new();
	d1->sent_messages=pqueue_new();
	d1->buffered_app_data.q=pqueue_new();

	if ( s->server)
		{
@@ -121,12 +122,13 @@ int dtls1_new(SSL *s)
		}

	if( ! d1->unprocessed_rcds.q || ! d1->processed_rcds.q 
        || ! d1->buffered_messages || ! d1->sent_messages)
        || ! d1->buffered_messages || ! d1->sent_messages || ! d1->buffered_app_data.q)
		{
        if ( d1->unprocessed_rcds.q) pqueue_free(d1->unprocessed_rcds.q);
        if ( d1->processed_rcds.q) pqueue_free(d1->processed_rcds.q);
        if ( d1->buffered_messages) pqueue_free(d1->buffered_messages);
		if ( d1->sent_messages) pqueue_free(d1->sent_messages);
		if ( d1->buffered_app_data.q) pqueue_free(d1->buffered_app_data.q);
		OPENSSL_free(d1);
		return (0);
		}
@@ -175,6 +177,15 @@ void dtls1_free(SSL *s)
        }
	pqueue_free(s->d1->sent_messages);

	while ( (item = pqueue_pop(s->d1->buffered_app_data.q)) != NULL)
	{
		frag = (hm_fragment *)item->data;
		OPENSSL_free(frag->fragment);
		OPENSSL_free(frag);
		pitem_free(item);
	}
	pqueue_free(s->d1->buffered_app_data.q);
	
	pq_64bit_free(&(s->d1->bitmap.map));
	pq_64bit_free(&(s->d1->bitmap.max_seq_num));

+46 −11
Original line number Diff line number Diff line
@@ -703,6 +703,23 @@ start:
	 * s->s3->rrec.length,  - number of bytes. */
	rr = &(s->s3->rrec);

	/* We are not handshaking and have no data yet,
	 * so process data buffered during the last handshake
	 * in advance, if any.
	 */
	if (s->state == SSL_ST_OK && rr->length == 0)
		{
		pitem *item;
		item = pqueue_pop(s->d1->buffered_app_data.q);
		if (item)
			{
			dtls1_copy_record(s, item);

			OPENSSL_free(item->data);
			pitem_free(item);
			}
		}
		
	/* get new packet if necessary */
	if ((rr->length == 0) || (s->rstate == SSL_ST_READ_BODY))
		{
@@ -724,9 +741,14 @@ start:
	                               * reset by ssl3_get_finished */
		&& (rr->type != SSL3_RT_HANDSHAKE))
		{
		al=SSL_AD_UNEXPECTED_MESSAGE;
		SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_DATA_BETWEEN_CCS_AND_FINISHED);
		goto err;
		/* We now have application data between CCS and Finished.
		 * Most likely the packets were reordered on their way, so
		 * buffer the application data for later processing rather
		 * than dropping the connection.
		 */
		dtls1_buffer_record(s, &(s->d1->buffered_app_data), 0);
		rr->length = 0;
		goto start;
		}

	/* If the other end has shut down, throw anything we read away
@@ -796,16 +818,29 @@ start:
			dest = s->d1->alert_fragment;
			dest_len = &s->d1->alert_fragment_len;
			}
                /* else it's a CCS message, or it's wrong */
		/* else it's a CCS message, or application data or wrong */
		else if (rr->type != SSL3_RT_CHANGE_CIPHER_SPEC)
			{
			/* Application data while renegotiating
			 * is allowed. Try again reading.
			 */
			if (rr->type == SSL3_RT_APPLICATION_DATA)
				{
				BIO *bio;
				s->s3->in_read_app_data=2;
				bio=SSL_get_rbio(s);
				s->rwstate=SSL_READING;
				BIO_clear_retry_flags(bio);
				BIO_set_retry_read(bio);
				return(-1);
				}

			/* Not certain if this is the right error handling */
			al=SSL_AD_UNEXPECTED_MESSAGE;
			SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_UNEXPECTED_RECORD);
			goto f_err;
			}


		if (dest_maxlen > 0)
			{
            /* XDTLS:  In a pathalogical case, the Client Hello
+7 −0
Original line number Diff line number Diff line
@@ -195,6 +195,13 @@ typedef struct dtls1_state_st
	/* Buffered (sent) handshake records */
	pqueue sent_messages;

	/* Buffered application records.
	 * Only for records between CCS and Finished
	 * to prevent either protocol violation or
	 * unnecessary message loss.
	 */
	record_pqueue buffered_app_data;

	unsigned int mtu; /* max wire packet size */

	struct hm_header_st w_msg_hdr;