DTLS1_RECORD_DATA *rdata;
pitem *item;
+ /* Limit the size of the queue to prevent DOS attacks */
+ if (pqueue_size(queue->q) >= 100)
+ return 0;
+
rdata = OPENSSL_malloc(sizeof(DTLS1_RECORD_DATA));
item = pitem_new(priority, rdata);
if (rdata == NULL || item == NULL)
{
if (version != s->version)
{
- SSLerr(SSL_F_DTLS1_GET_RECORD,SSL_R_WRONG_VERSION_NUMBER);
- /* Send back error using their
- * version number :-) */
- s->version=version;
- al=SSL_AD_PROTOCOL_VERSION;
- goto f_err;
+ /* unexpected version, silently discard */
+ rr->length = 0;
+ s->packet_length = 0;
+ goto again;
}
}
- if ((version & 0xff00) != (DTLS1_VERSION & 0xff00))
+ if ((version & 0xff00) != (s->version & 0xff00))
{
- SSLerr(SSL_F_DTLS1_GET_RECORD,SSL_R_WRONG_VERSION_NUMBER);
- goto err;
+ /* wrong version, silently discard record */
+ rr->length = 0;
+ s->packet_length = 0;
+ goto again;
}
if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH)
{
- al=SSL_AD_RECORD_OVERFLOW;
- SSLerr(SSL_F_DTLS1_GET_RECORD,SSL_R_PACKET_LENGTH_TOO_LONG);
- goto f_err;
+ /* record too long, silently discard it */
+ rr->length = 0;
+ s->packet_length = 0;
+ goto again;
}
/* now s->rstate == SSL_ST_READ_BODY */
/* this packet contained a partial record, dump it */
if ( n != i)
{
+ rr->length = 0;
s->packet_length = 0;
goto again;
}
bitmap = dtls1_get_bitmap(s, rr, &is_next_epoch);
if ( bitmap == NULL)
{
+ rr->length = 0;
s->packet_length = 0; /* dump this record */
goto again; /* get another record */
}
{
dtls1_record_bitmap_update(s, bitmap);
dtls1_buffer_record(s, &(s->d1->unprocessed_rcds), rr->seq_num);
+ rr->length = 0;
s->packet_length = 0;
goto again;
}
pitem_free(item);
}
}
-
+
+ /* Check for timeout */
+ if (dtls1_is_timer_expired(s))
+ {
+ if (dtls1_read_failed(s, -1) > 0);
+ goto start;
+ }
+
/* get new packet if necessary */
if ((rr->length == 0) || (s->rstate == SSL_ST_READ_BODY))
{
if (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC)
{
struct ccs_header_st ccs_hdr;
+ unsigned int ccs_hdr_len = DTLS1_CCS_HEADER_LENGTH;
dtls1_get_ccs_header(rr->data, &ccs_hdr);
+ if (s->version == DTLS1_BAD_VER)
+ ccs_hdr_len = 3;
+
/* 'Change Cipher Spec' is just a single byte, so we know
* exactly what the record payload has to look like */
/* XDTLS: check that epoch is consistent */
- if ( (rr->length != DTLS1_CCS_HEADER_LENGTH) ||
+ if ( (rr->length != ccs_hdr_len) ||
(rr->off != 0) || (rr->data[0] != SSL3_MT_CCS))
{
i=SSL_AD_ILLEGAL_PARAMETER;
s->msg_callback(0, s->version, SSL3_RT_CHANGE_CIPHER_SPEC,
rr->data, 1, s, s->msg_callback_arg);
+ /* We can't process a CCS now, because previous handshake
+ * messages are still missing, so just drop it.
+ */
+ if (!s->d1->change_cipher_spec_ok)
+ {
+ goto start;
+ }
+
+ s->d1->change_cipher_spec_ok = 0;
+
s->s3->change_cipher_spec=1;
if (!ssl3_do_change_cipher_spec(s))
goto err;
/* do this whenever CCS is processed */
dtls1_reset_seq_numbers(s, SSL3_CC_READ);
+ if (s->version == DTLS1_BAD_VER)
+ s->d1->handshake_read_seq++;
+
goto start;
}
#if 0
/* 'create_empty_fragment' is true only when this function calls itself */
if (!clear && !create_empty_fragment && !s->s3->empty_fragment_done
- && SSL_version(s) != DTLS1_VERSION)
+ && SSL_version(s) != DTLS1_VERSION && SSL_version(s) != DTLS1_BAD_VER)
{
/* countermeasure against known-IV weakness in CBC ciphersuites
* (see http://www.openssl.org/~bodo/tls-cbc.txt)
s->s3->empty_fragment_done = 1;
}
#endif
-
p = wb->buf + prefix_len;
/* write the header */