if (is_complete) for (ii = (((msg_len) - 1) >> 3) - 1; ii >= 0 ; ii--) \
if (bitmask[ii] != 0xff) { is_complete = 0; break; } }
-#if 0
-# define RSMBLY_BITMASK_PRINT(bitmask, msg_len) { \
- long ii; \
- printf("bitmask: "); for (ii = 0; ii < (msg_len); ii++) \
- printf("%d ", (bitmask[ii >> 3] & (1 << (ii & 7))) >> (ii & 7)); \
- printf("\n"); }
-#endif
-
static unsigned char bitmask_start_values[] =
{ 0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80 };
static unsigned char bitmask_end_values[] =
unsigned char *buf = NULL;
unsigned char *bitmask = NULL;
- frag = (hm_fragment *)OPENSSL_malloc(sizeof(hm_fragment));
+ frag = OPENSSL_malloc(sizeof(*frag));
if (frag == NULL)
return NULL;
if (frag_len) {
- buf = (unsigned char *)OPENSSL_malloc(frag_len);
+ buf = OPENSSL_malloc(frag_len);
if (buf == NULL) {
OPENSSL_free(frag);
return NULL;
/* Initialize reassembly bitmask if necessary */
if (reassembly) {
- bitmask =
- (unsigned char *)OPENSSL_malloc(RSMBLY_BITMASK_SIZE(frag_len));
+ bitmask = OPENSSL_malloc(RSMBLY_BITMASK_SIZE(frag_len));
if (bitmask == NULL) {
- if (buf != NULL)
- OPENSSL_free(buf);
+ OPENSSL_free(buf);
OPENSSL_free(frag);
return NULL;
}
void dtls1_hm_fragment_free(hm_fragment *frag)
{
-
+ if (!frag)
+ return;
if (frag->msg_header.is_ccs) {
EVP_CIPHER_CTX_free(frag->msg_header.
saved_retransmit_state.enc_write_ctx);
EVP_MD_CTX_destroy(frag->msg_header.
saved_retransmit_state.write_hash);
}
- if (frag->fragment)
- OPENSSL_free(frag->fragment);
- if (frag->reassembly)
- OPENSSL_free(frag->reassembly);
+ OPENSSL_free(frag->fragment);
+ OPENSSL_free(frag->reassembly);
OPENSSL_free(frag);
}
}
msg_hdr = &s->d1->r_msg_hdr;
- memset(msg_hdr, 0x00, sizeof(struct hm_header_st));
+ memset(msg_hdr, 0, sizeof(*msg_hdr));
again:
i = dtls1_get_message_fragment(s, st1, stn, max, ok);
return i;
}
+ if (mt >= 0 && s->s3->tmp.message_type != mt) {
+ al = SSL_AD_UNEXPECTED_MESSAGE;
+ SSLerr(SSL_F_DTLS1_GET_MESSAGE, SSL_R_UNEXPECTED_MESSAGE);
+ goto f_err;
+ }
+
p = (unsigned char *)s->init_buf->data;
msg_len = msg_hdr->msg_len;
s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE,
p, msg_len, s, s->msg_callback_arg);
- memset(msg_hdr, 0x00, sizeof(struct hm_header_st));
+ memset(msg_hdr, 0, sizeof(*msg_hdr));
/* Don't change sequence numbers while listening */
if (!s->d1->listen)
static int dtls1_retrieve_buffered_fragment(SSL *s, long max, int *ok)
{
- /*-
- * (0) check whether the desired fragment is available
- * if so:
- * (1) copy over the fragment to s->init_buf->data[]
- * (2) update s->init_num
- */
+ /*-
+ * (0) check whether the desired fragment is available
+ * if so:
+ * (1) copy over the fragment to s->init_buf->data[]
+ * (2) update s->init_num
+ */
pitem *item;
hm_fragment *frag;
int al;
return DTLS1_HM_FRAGMENT_RETRY;
err:
- if (frag != NULL && item == NULL)
+ if (item == NULL)
dtls1_hm_fragment_free(frag);
*ok = 0;
return i;
return DTLS1_HM_FRAGMENT_RETRY;
err:
- if (frag != NULL && item == NULL)
+ if (item == NULL)
dtls1_hm_fragment_free(frag);
*ok = 0;
return i;
/*-
* for these 2 messages, we need to
* ssl->enc_read_ctx re-init
- * ssl->s3->read_sequence zero
+ * ssl->rlayer.read_sequence zero
* ssl->s3->read_mac_secret re-init
* ssl->session->read_sym_enc assign
* ssl->session->read_compression assign
s->d1->handshake_write_seq, 0, 0);
/* buffer the message to handle re-xmits */
- dtls1_buffer_message(s, 1);
+ if (!dtls1_buffer_message(s, 1)) {
+ SSLerr(SSL_F_DTLS1_SEND_CHANGE_CIPHER_SPEC, ERR_R_INTERNAL_ERROR);
+ return -1;
+ }
s->state = b;
}
BIO_set_flags(SSL_get_rbio(s), BIO_FLAGS_READ);
return code;
}
-#if 0 /* for now, each alert contains only one
- * record number */
- item = pqueue_peek(state->rcvd_records);
- if (item) {
- /* send an alert immediately for all the missing records */
- } else
-#endif
-
-#if 0 /* no more alert sending, just retransmit the
- * last set of messages */
- if (state->timeout.read_timeouts >= DTLS1_TMO_READ_COUNT)
- ssl3_send_alert(s, SSL3_AL_WARNING,
- DTLS1_AD_MISSING_HANDSHAKE_MESSAGE);
-#endif
return dtls1_handle_timeout(s);
}
memcpy(frag->fragment, s->init_buf->data, s->init_num);
if (is_ccs) {
+ /* For DTLS1_BAD_VER the header length is non-standard */
OPENSSL_assert(s->d1->w_msg_hdr.msg_len +
- DTLS1_CCS_HEADER_LENGTH == (unsigned int)s->init_num);
+ ((s->version==DTLS1_BAD_VER)?3:DTLS1_CCS_HEADER_LENGTH)
+ == (unsigned int)s->init_num);
} else {
OPENSSL_assert(s->d1->w_msg_hdr.msg_len +
DTLS1_HM_HEADER_LENGTH == (unsigned int)s->init_num);
frag->msg_header.saved_retransmit_state.write_hash = s->write_hash;
frag->msg_header.saved_retransmit_state.compress = s->compress;
frag->msg_header.saved_retransmit_state.session = s->session;
- frag->msg_header.saved_retransmit_state.epoch = s->d1->w_epoch;
+ frag->msg_header.saved_retransmit_state.epoch =
+ DTLS_RECORD_LAYER_get_w_epoch(&s->rlayer);
memset(seq64be, 0, sizeof(seq64be));
seq64be[6] =
dtls1_hm_fragment_free(frag);
return 0;
}
-#if 0
- fprintf(stderr, "buffered messge: \ttype = %xx\n", msg_buf->type);
- fprintf(stderr, "\t\t\t\t\tlen = %d\n", msg_buf->len);
- fprintf(stderr, "\t\t\t\t\tseq_num = %d\n", msg_buf->seq_num);
-#endif
pqueue_insert(s->d1->sent_messages, item);
return 1;
unsigned long header_length;
unsigned char seq64be[8];
struct dtls1_retransmit_state saved_state;
- unsigned char save_write_sequence[8];
- /*-
- OPENSSL_assert(s->init_num == 0);
- OPENSSL_assert(s->init_off == 0);
- */
+ /*-
+ OPENSSL_assert(s->init_num == 0);
+ OPENSSL_assert(s->init_off == 0);
+ */
/* XDTLS: the requested message ought to be found, otherwise error */
memset(seq64be, 0, sizeof(seq64be));
saved_state.write_hash = s->write_hash;
saved_state.compress = s->compress;
saved_state.session = s->session;
- saved_state.epoch = s->d1->w_epoch;
- saved_state.epoch = s->d1->w_epoch;
+ saved_state.epoch = DTLS_RECORD_LAYER_get_w_epoch(&s->rlayer);
s->d1->retransmitting = 1;
s->write_hash = frag->msg_header.saved_retransmit_state.write_hash;
s->compress = frag->msg_header.saved_retransmit_state.compress;
s->session = frag->msg_header.saved_retransmit_state.session;
- s->d1->w_epoch = frag->msg_header.saved_retransmit_state.epoch;
-
- if (frag->msg_header.saved_retransmit_state.epoch ==
- saved_state.epoch - 1) {
- memcpy(save_write_sequence, s->s3->write_sequence,
- sizeof(s->s3->write_sequence));
- memcpy(s->s3->write_sequence, s->d1->last_write_sequence,
- sizeof(s->s3->write_sequence));
- }
+ DTLS_RECORD_LAYER_set_saved_w_epoch(&s->rlayer,
+ frag->msg_header.saved_retransmit_state.epoch);
ret = dtls1_do_write(s, frag->msg_header.is_ccs ?
SSL3_RT_CHANGE_CIPHER_SPEC : SSL3_RT_HANDSHAKE);
s->write_hash = saved_state.write_hash;
s->compress = saved_state.compress;
s->session = saved_state.session;
- s->d1->w_epoch = saved_state.epoch;
-
- if (frag->msg_header.saved_retransmit_state.epoch ==
- saved_state.epoch - 1) {
- memcpy(s->d1->last_write_sequence, s->s3->write_sequence,
- sizeof(s->s3->write_sequence));
- memcpy(s->s3->write_sequence, save_write_sequence,
- sizeof(s->s3->write_sequence));
- }
+ DTLS_RECORD_LAYER_set_saved_w_epoch(&s->rlayer, saved_state.epoch);
s->d1->retransmitting = 0;
}
}
-unsigned char *dtls1_set_message_header(SSL *s, unsigned char *p,
+void dtls1_set_message_header(SSL *s, unsigned char *p,
unsigned char mt, unsigned long len,
unsigned long frag_off,
unsigned long frag_len)
dtls1_set_message_header_int(s, mt, len, s->d1->handshake_write_seq,
frag_off, frag_len);
-
- return p += DTLS1_HM_HEADER_LENGTH;
}
/* don't actually do the writing, wait till the MTU has been retrieved */
void
dtls1_get_message_header(unsigned char *data, struct hm_header_st *msg_hdr)
{
- memset(msg_hdr, 0x00, sizeof(struct hm_header_st));
+ memset(msg_hdr, 0, sizeof(*msg_hdr));
msg_hdr->type = *(data++);
n2l3(data, msg_hdr->msg_len);
n2l3(data, msg_hdr->frag_len);
}
-void dtls1_get_ccs_header(unsigned char *data, struct ccs_header_st *ccs_hdr)
-{
- memset(ccs_hdr, 0x00, sizeof(struct ccs_header_st));
-
- ccs_hdr->type = *(data++);
-}
-
int dtls1_shutdown(SSL *s)
{
int ret;
}
#ifndef OPENSSL_NO_HEARTBEATS
-int dtls1_process_heartbeat(SSL *s)
+int dtls1_process_heartbeat(SSL *s, unsigned char *p, unsigned int length)
{
- unsigned char *p = &s->s3->rrec.data[0], *pl;
+ unsigned char *pl;
unsigned short hbtype;
unsigned int payload;
unsigned int padding = 16; /* Use minimum padding */
if (s->msg_callback)
s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT,
- &s->s3->rrec.data[0], s->s3->rrec.length,
- s, s->msg_callback_arg);
+ p, length, s, s->msg_callback_arg);
/* Read type and payload length first */
- if (1 + 2 + 16 > s->s3->rrec.length)
+ if (1 + 2 + 16 > length)
return 0; /* silently discard */
- if (s->s3->rrec.length > SSL3_RT_MAX_PLAIN_LENGTH)
+ if (length > SSL3_RT_MAX_PLAIN_LENGTH)
return 0; /* silently discard per RFC 6520 sec. 4 */
hbtype = *p++;
n2s(p, payload);
- if (1 + 2 + payload + 16 > s->s3->rrec.length)
+ if (1 + 2 + payload + 16 > length)
return 0; /* silently discard per RFC 6520 sec. 4 */
pl = p;
memcpy(bp, pl, payload);
bp += payload;
/* Random padding */
- RAND_pseudo_bytes(bp, padding);
+ if (RAND_bytes(bp, padding) <= 0) {
+ OPENSSL_free(buffer);
+ return -1;
+ }
r = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buffer, write_length);
int dtls1_heartbeat(SSL *s)
{
unsigned char *buf, *p;
- int ret;
+ int ret = -1;
unsigned int payload = 18; /* Sequence number + random bytes */
unsigned int padding = 16; /* Use minimum padding */
*/
OPENSSL_assert(payload + padding <= 16381);
- /*-
- * Create HeartBeat message, we just use a sequence number
- * as payload to distuingish different messages and add
- * some random stuff.
- * - Message Type, 1 byte
- * - Payload Length, 2 bytes (unsigned int)
- * - Payload, the sequence number (2 bytes uint)
- * - Payload, random bytes (16 bytes uint)
- * - Padding
- */
+ /*-
+ * Create HeartBeat message, we just use a sequence number
+ * as payload to distuingish different messages and add
+ * some random stuff.
+ * - Message Type, 1 byte
+ * - Payload Length, 2 bytes (unsigned int)
+ * - Payload, the sequence number (2 bytes uint)
+ * - Payload, random bytes (16 bytes uint)
+ * - Padding
+ */
buf = OPENSSL_malloc(1 + 2 + payload + padding);
if (buf == NULL) {
SSLerr(SSL_F_DTLS1_HEARTBEAT, ERR_R_MALLOC_FAILURE);
/* Sequence number */
s2n(s->tlsext_hb_seq, p);
/* 16 random bytes */
- RAND_pseudo_bytes(p, 16);
+ if (RAND_bytes(p, 16) <= 0) {
+ SSLerr(SSL_F_DTLS1_HEARTBEAT, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
p += 16;
/* Random padding */
- RAND_pseudo_bytes(p, padding);
+ if (RAND_bytes(p, padding) <= 0) {
+ SSLerr(SSL_F_DTLS1_HEARTBEAT, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
ret = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buf, 3 + payload + padding);
if (ret >= 0) {
s->tlsext_hb_pending = 1;
}
+ err:
OPENSSL_free(buf);
return ret;