X-Git-Url: https://git.openssl.org/?a=blobdiff_plain;f=ssl%2Frecord%2Fd1_pkt.c;h=76bea7a29b42d7398dbb892b4acf5d6736e920ed;hb=24a1e2f2ec1553c2cc26574bdb48b5d8c1b913f7;hp=02b0f52eb1f99088042c7f7b31cacd11662058b1;hpb=40f37188a63c988c66bfece95280b67158998e64;p=openssl.git diff --git a/ssl/record/d1_pkt.c b/ssl/record/d1_pkt.c index 02b0f52eb1..76bea7a29b 100644 --- a/ssl/record/d1_pkt.c +++ b/ssl/record/d1_pkt.c @@ -131,14 +131,35 @@ int DTLS_RECORD_LAYER_new(RECORD_LAYER *rl) return (0); } + rl->d = d; - DTLS_RECORD_LAYER_clear(rl); + + d->unprocessed_rcds.q = pqueue_new(); + d->processed_rcds.q = pqueue_new(); + d->buffered_app_data.q = pqueue_new(); + + if (!d->unprocessed_rcds.q || !d->processed_rcds.q + || !d->buffered_app_data.q) { + if (d->unprocessed_rcds.q) + pqueue_free(d->unprocessed_rcds.q); + if (d->processed_rcds.q) + pqueue_free(d->processed_rcds.q); + if (d->buffered_app_data.q) + pqueue_free(d->buffered_app_data.q); + OPENSSL_free(d); + rl->d = NULL; + return (0); + } return 1; } void DTLS_RECORD_LAYER_free(RECORD_LAYER *rl) { + DTLS_RECORD_LAYER_clear(rl); + pqueue_free(rl->d->unprocessed_rcds.q); + pqueue_free(rl->d->processed_rcds.q); + pqueue_free(rl->d->buffered_app_data.q); OPENSSL_free(rl->d); rl->d = NULL; } @@ -146,68 +167,48 @@ void DTLS_RECORD_LAYER_free(RECORD_LAYER *rl) void DTLS_RECORD_LAYER_clear(RECORD_LAYER *rl) { DTLS_RECORD_LAYER *d; - + pitem *item = NULL; + DTLS1_RECORD_DATA *rdata; + pqueue unprocessed_rcds; + pqueue processed_rcds; + pqueue buffered_app_data; + d = rl->d; - memset(d, 0, sizeof *d); -} + + while ((item = pqueue_pop(d->unprocessed_rcds.q)) != NULL) { + rdata = (DTLS1_RECORD_DATA *)item->data; + if (rdata->rbuf.buf) { + OPENSSL_free(rdata->rbuf.buf); + } + OPENSSL_free(item->data); + pitem_free(item); + } -/* mod 128 saturating subtract of two 64-bit values in big-endian order */ -static int satsub64be(const unsigned char *v1, const unsigned char *v2) -{ - int ret, sat, brw, i; - - if (sizeof(long) == 8) - do { - const union { - long one; - char little; - } is_endian = { - 1 - }; - long l; - - if (is_endian.little) - break; - /* not reached on little-endians */ - /* - * following test is redundant, because input is always aligned, - * but I take no chances... - */ - if (((size_t)v1 | (size_t)v2) & 0x7) - break; - - l = *((long *)v1); - l -= *((long *)v2); - if (l > 128) - return 128; - else if (l < -128) - return -128; - else - return (int)l; - } while (0); - - ret = (int)v1[7] - (int)v2[7]; - sat = 0; - brw = ret >> 8; /* brw is either 0 or -1 */ - if (ret & 0x80) { - for (i = 6; i >= 0; i--) { - brw += (int)v1[i] - (int)v2[i]; - sat |= ~brw; - brw >>= 8; + while ((item = pqueue_pop(d->processed_rcds.q)) != NULL) { + rdata = (DTLS1_RECORD_DATA *)item->data; + if (rdata->rbuf.buf) { + OPENSSL_free(rdata->rbuf.buf); } - } else { - for (i = 6; i >= 0; i--) { - brw += (int)v1[i] - (int)v2[i]; - sat |= brw; - brw >>= 8; + OPENSSL_free(item->data); + pitem_free(item); + } + + while ((item = pqueue_pop(d->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); } - brw <<= 8; /* brw is either 0 or -256 */ - if (sat & 0xff) - return brw | 0x80; - else - return brw + (ret & 0xFF); + unprocessed_rcds = d->unprocessed_rcds.q; + processed_rcds = d->processed_rcds.q; + buffered_app_data = d->buffered_app_data.q; + memset(d, 0, sizeof *d); + d->unprocessed_rcds.q = unprocessed_rcds; + d->processed_rcds.q = processed_rcds; + d->buffered_app_data.q = buffered_app_data; } static int have_handshake_fragment(SSL *s, int type, unsigned char *buf, @@ -322,25 +323,25 @@ int dtls1_retrieve_buffered_record(SSL *s, record_pqueue *queue) */ #define dtls1_get_unprocessed_record(s) \ dtls1_retrieve_buffered_record((s), \ - &((s)->d1->unprocessed_rcds)) + &((s)->rlayer.d->unprocessed_rcds)) int dtls1_process_buffered_records(SSL *s) { pitem *item; - item = pqueue_peek(s->d1->unprocessed_rcds.q); + item = pqueue_peek(s->rlayer.d->unprocessed_rcds.q); if (item) { /* Check if epoch is current. */ - if (s->d1->unprocessed_rcds.epoch != s->d1->r_epoch) + if (s->rlayer.d->unprocessed_rcds.epoch != s->rlayer.d->r_epoch) return (1); /* Nothing to do. */ /* Process all the records. */ - while (pqueue_peek(s->d1->unprocessed_rcds.q)) { + while (pqueue_peek(s->rlayer.d->unprocessed_rcds.q)) { dtls1_get_unprocessed_record(s); if (!dtls1_process_record(s)) return (0); - if (dtls1_buffer_record(s, &(s->d1->processed_rcds), + if (dtls1_buffer_record(s, &(s->rlayer.d->processed_rcds), SSL3_RECORD_get_seq_num(&s->rlayer.rrec)) < 0) return -1; } @@ -350,8 +351,8 @@ int dtls1_process_buffered_records(SSL *s) * sync epoch numbers once all the unprocessed records have been * processed */ - s->d1->processed_rcds.epoch = s->d1->r_epoch; - s->d1->unprocessed_rcds.epoch = s->d1->r_epoch + 1; + s->rlayer.d->processed_rcds.epoch = s->rlayer.d->r_epoch; + s->rlayer.d->unprocessed_rcds.epoch = s->rlayer.d->r_epoch + 1; return (1); } @@ -412,7 +413,8 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) return ret; /* - * Now s->d1->handshake_fragment_len == 0 if type == SSL3_RT_HANDSHAKE. + * Now s->rlayer.d->handshake_fragment_len == 0 if + * type == SSL3_RT_HANDSHAKE. */ #ifndef OPENSSL_NO_SCTP @@ -456,7 +458,7 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) */ if (s->state == SSL_ST_OK && rr->length == 0) { pitem *item; - item = pqueue_pop(s->d1->buffered_app_data.q); + item = pqueue_pop(s->rlayer.d->buffered_app_data.q); if (item) { #ifndef OPENSSL_NO_SCTP /* Restore bio_dgram_sctp_rcvinfo struct */ @@ -506,8 +508,8 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) * the packets were reordered on their way, so buffer the application * data for later processing rather than dropping the connection. */ - if (dtls1_buffer_record(s, &(s->d1->buffered_app_data), rr->seq_num) < - 0) { + if (dtls1_buffer_record(s, &(s->rlayer.d->buffered_app_data), + rr->seq_num) < 0) { SSLerr(SSL_F_DTLS1_READ_BYTES, ERR_R_INTERNAL_ERROR); return -1; } @@ -599,13 +601,13 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) unsigned int *dest_len = NULL; if (rr->type == SSL3_RT_HANDSHAKE) { - dest_maxlen = sizeof s->d1->handshake_fragment; - dest = s->d1->handshake_fragment; - dest_len = &s->d1->handshake_fragment_len; + dest_maxlen = sizeof s->rlayer.d->handshake_fragment; + dest = s->rlayer.d->handshake_fragment; + dest_len = &s->rlayer.d->handshake_fragment_len; } else if (rr->type == SSL3_RT_ALERT) { - dest_maxlen = sizeof(s->d1->alert_fragment); - dest = s->d1->alert_fragment; - dest_len = &s->d1->alert_fragment_len; + dest_maxlen = sizeof(s->rlayer.d->alert_fragment); + dest = s->rlayer.d->alert_fragment; + dest_len = &s->rlayer.d->alert_fragment_len; } #ifndef OPENSSL_NO_HEARTBEATS else if (rr->type == TLS1_RT_HEARTBEAT) { @@ -673,21 +675,21 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) } /*- - * s->d1->handshake_fragment_len == 12 iff rr->type == SSL3_RT_HANDSHAKE; - * s->d1->alert_fragment_len == 7 iff rr->type == SSL3_RT_ALERT. + * s->rlayer.d->handshake_fragment_len == 12 iff rr->type == SSL3_RT_HANDSHAKE; + * s->rlayer.d->alert_fragment_len == 7 iff rr->type == SSL3_RT_ALERT. * (Possibly rr is 'empty' now, i.e. rr->length may be 0.) */ /* If we are a client, check for an incoming 'Hello Request': */ if ((!s->server) && - (s->d1->handshake_fragment_len >= DTLS1_HM_HEADER_LENGTH) && - (s->d1->handshake_fragment[0] == SSL3_MT_HELLO_REQUEST) && + (s->rlayer.d->handshake_fragment_len >= DTLS1_HM_HEADER_LENGTH) && + (s->rlayer.d->handshake_fragment[0] == SSL3_MT_HELLO_REQUEST) && (s->session != NULL) && (s->session->cipher != NULL)) { - s->d1->handshake_fragment_len = 0; + s->rlayer.d->handshake_fragment_len = 0; - if ((s->d1->handshake_fragment[1] != 0) || - (s->d1->handshake_fragment[2] != 0) || - (s->d1->handshake_fragment[3] != 0)) { + if ((s->rlayer.d->handshake_fragment[1] != 0) || + (s->rlayer.d->handshake_fragment[2] != 0) || + (s->rlayer.d->handshake_fragment[3] != 0)) { al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_BAD_HELLO_REQUEST); goto err; @@ -699,7 +701,7 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) if (s->msg_callback) s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, - s->d1->handshake_fragment, 4, s, + s->rlayer.d->handshake_fragment, 4, s, s->msg_callback_arg); if (SSL_is_init_finished(s) && @@ -744,15 +746,16 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) goto start; } - if (s->d1->alert_fragment_len >= DTLS1_AL_HEADER_LENGTH) { - int alert_level = s->d1->alert_fragment[0]; - int alert_descr = s->d1->alert_fragment[1]; + if (s->rlayer.d->alert_fragment_len >= DTLS1_AL_HEADER_LENGTH) { + int alert_level = s->rlayer.d->alert_fragment[0]; + int alert_descr = s->rlayer.d->alert_fragment[1]; - s->d1->alert_fragment_len = 0; + s->rlayer.d->alert_fragment_len = 0; if (s->msg_callback) s->msg_callback(0, s->version, SSL3_RT_ALERT, - s->d1->alert_fragment, 2, s, s->msg_callback_arg); + s->rlayer.d->alert_fragment, 2, s, + s->msg_callback_arg); if (s->info_callback != NULL) cb = s->info_callback; @@ -791,7 +794,7 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) if (alert_descr == DTLS1_AD_MISSING_HANDSHAKE_MESSAGE) { unsigned short seq; unsigned int frag_off; - unsigned char *p = &(s->d1->alert_fragment[2]); + unsigned char *p = &(s->rlayer.d->alert_fragment[2]); n2s(p, seq); n2l3(p, frag_off); @@ -903,13 +906,13 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) /* * Unexpected handshake message (Client Hello, or protocol violation) */ - if ((s->d1->handshake_fragment_len >= DTLS1_HM_HEADER_LENGTH) && + if ((s->rlayer.d->handshake_fragment_len >= DTLS1_HM_HEADER_LENGTH) && !s->in_handshake) { struct hm_header_st msg_hdr; /* this may just be a stale retransmit */ dtls1_get_message_header(rr->data, &msg_hdr); - if (rr->epoch != s->d1->r_epoch) { + if (rr->epoch != s->rlayer.d->r_epoch) { rr->length = 0; goto start; } @@ -1026,24 +1029,25 @@ have_handshake_fragment(SSL *s, int type, unsigned char *buf, int len, int peek) { - if ((type == SSL3_RT_HANDSHAKE) && (s->d1->handshake_fragment_len > 0)) + if ((type == SSL3_RT_HANDSHAKE) + && (s->rlayer.d->handshake_fragment_len > 0)) /* (partially) satisfy request from storage */ { - unsigned char *src = s->d1->handshake_fragment; + unsigned char *src = s->rlayer.d->handshake_fragment; unsigned char *dst = buf; unsigned int k, n; /* peek == 0 */ n = 0; - while ((len > 0) && (s->d1->handshake_fragment_len > 0)) { + while ((len > 0) && (s->rlayer.d->handshake_fragment_len > 0)) { *dst++ = *src++; len--; - s->d1->handshake_fragment_len--; + s->rlayer.d->handshake_fragment_len--; n++; } /* move any remaining fragment bytes: */ - for (k = 0; k < s->d1->handshake_fragment_len; k++) - s->d1->handshake_fragment[k] = *src++; + for (k = 0; k < s->rlayer.d->handshake_fragment_len; k++) + s->rlayer.d->handshake_fragment[k] = *src++; return n; } @@ -1201,7 +1205,7 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf, /* there's only one epoch between handshake and app data */ - s2n(s->d1->w_epoch, pseq); + s2n(s->rlayer.d->w_epoch, pseq); /* XDTLS: ?? */ /* @@ -1252,48 +1256,6 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf, return -1; } -int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap) -{ - int cmp; - unsigned int shift; - const unsigned char *seq = s->rlayer.read_sequence; - - cmp = satsub64be(seq, bitmap->max_seq_num); - if (cmp > 0) { - SSL3_RECORD_set_seq_num(&s->rlayer.rrec, seq); - return 1; /* this record in new */ - } - shift = -cmp; - if (shift >= sizeof(bitmap->map) * 8) - return 0; /* stale, outside the window */ - else if (bitmap->map & (1UL << shift)) - return 0; /* record previously received */ - - SSL3_RECORD_set_seq_num(&s->rlayer.rrec, seq); - return 1; -} - -void dtls1_record_bitmap_update(SSL *s, DTLS1_BITMAP *bitmap) -{ - int cmp; - unsigned int shift; - const unsigned char *seq = s->rlayer.read_sequence; - - cmp = satsub64be(seq, bitmap->max_seq_num); - if (cmp > 0) { - shift = cmp; - if (shift < sizeof(bitmap->map) * 8) - bitmap->map <<= shift, bitmap->map |= 1UL; - else - bitmap->map = 1UL; - memcpy(bitmap->max_seq_num, seq, 8); - } else { - shift = -cmp; - if (shift < sizeof(bitmap->map) * 8) - bitmap->map |= 1UL << shift; - } -} - DTLS1_BITMAP *dtls1_get_bitmap(SSL *s, SSL3_RECORD *rr, unsigned int *is_next_epoch) { @@ -1301,14 +1263,14 @@ DTLS1_BITMAP *dtls1_get_bitmap(SSL *s, SSL3_RECORD *rr, *is_next_epoch = 0; /* In current epoch, accept HM, CCS, DATA, & ALERT */ - if (rr->epoch == s->d1->r_epoch) - return &s->d1->bitmap; + if (rr->epoch == s->rlayer.d->r_epoch) + return &s->rlayer.d->bitmap; /* Only HM and ALERT messages can be from the next epoch */ - else if (rr->epoch == (unsigned long)(s->d1->r_epoch + 1) && - (rr->type == SSL3_RT_HANDSHAKE || rr->type == SSL3_RT_ALERT)) { + else if (rr->epoch == (unsigned long)(s->rlayer.d->r_epoch + 1) && + (rr->type == SSL3_RT_HANDSHAKE || rr->type == SSL3_RT_ALERT)) { *is_next_epoch = 1; - return &s->d1->next_bitmap; + return &s->rlayer.d->next_bitmap; } return NULL; @@ -1321,14 +1283,15 @@ void dtls1_reset_seq_numbers(SSL *s, int rw) if (rw & SSL3_CC_READ) { seq = s->rlayer.read_sequence; - s->d1->r_epoch++; - memcpy(&(s->d1->bitmap), &(s->d1->next_bitmap), sizeof(DTLS1_BITMAP)); - memset(&(s->d1->next_bitmap), 0x00, sizeof(DTLS1_BITMAP)); + s->rlayer.d->r_epoch++; + memcpy(&(s->rlayer.d->bitmap), &(s->rlayer.d->next_bitmap), + sizeof(DTLS1_BITMAP)); + memset(&(s->rlayer.d->next_bitmap), 0x00, sizeof(DTLS1_BITMAP)); } else { seq = s->rlayer.write_sequence; memcpy(s->d1->last_write_sequence, seq, sizeof(s->rlayer.write_sequence)); - s->d1->w_epoch++; + s->rlayer.d->w_epoch++; } memset(seq, 0x00, seq_bytes);