PR: 1827
Submitted by: Robin Seggelmann <seggelmann@fh-muenster.de> Approved by: steve@openssl.org Fix application data in handshake bug.
This commit is contained in:
parent
4e319926d7
commit
6252f3bc7c
3 changed files with 65 additions and 12 deletions
13
ssl/d1_lib.c
13
ssl/d1_lib.c
|
@ -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));
|
||||
|
||||
|
|
57
ssl/d1_pkt.c
57
ssl/d1_pkt.c
|
@ -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,15 +818,28 @@ start:
|
|||
dest = s->d1->alert_fragment;
|
||||
dest_len = &s->d1->alert_fragment_len;
|
||||
}
|
||||
/* else it's a CCS message, or it's wrong */
|
||||
else if (rr->type != SSL3_RT_CHANGE_CIPHER_SPEC)
|
||||
{
|
||||
/* 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;
|
||||
}
|
||||
/* 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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue