X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=ssl%2Frecord%2Frec_layer_d1.c;h=d91de4d4a0d90a15698f110a5d140d1270b604f4;hp=c58af7f36abeefa282337798721e6234440bdcf8;hb=8723588e1b9a13511ffd7b806c73293120bc1f44;hpb=747e16398d704a667cc99f8a0b1912c36b7de52d diff --git a/ssl/record/rec_layer_d1.c b/ssl/record/rec_layer_d1.c index c58af7f36a..d91de4d4a0 100644 --- a/ssl/record/rec_layer_d1.c +++ b/ssl/record/rec_layer_d1.c @@ -127,9 +127,8 @@ int DTLS_RECORD_LAYER_new(RECORD_LAYER *rl) { DTLS_RECORD_LAYER *d; - if ((d = OPENSSL_malloc(sizeof *d)) == NULL) { + if ((d = OPENSSL_malloc(sizeof(*d))) == NULL) return (0); - } rl->d = d; @@ -140,12 +139,9 @@ int DTLS_RECORD_LAYER_new(RECORD_LAYER *rl) 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); + pqueue_free(d->unprocessed_rcds.q); + pqueue_free(d->processed_rcds.q); + pqueue_free(d->buffered_app_data.q); OPENSSL_free(d); rl->d = NULL; return (0); @@ -177,27 +173,21 @@ void DTLS_RECORD_LAYER_clear(RECORD_LAYER *rl) 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(rdata->rbuf.buf); OPENSSL_free(item->data); pitem_free(item); } while ((item = pqueue_pop(d->processed_rcds.q)) != NULL) { rdata = (DTLS1_RECORD_DATA *)item->data; - if (rdata->rbuf.buf) { - OPENSSL_free(rdata->rbuf.buf); - } + OPENSSL_free(rdata->rbuf.buf); 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(rdata->rbuf.buf); OPENSSL_free(item->data); pitem_free(item); } @@ -205,7 +195,7 @@ void DTLS_RECORD_LAYER_clear(RECORD_LAYER *rl) 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); + 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; @@ -236,6 +226,12 @@ void DTLS_RECORD_LAYER_resync_write(RECORD_LAYER *rl) memcpy(rl->write_sequence, rl->read_sequence, sizeof(rl->write_sequence)); } + +void DTLS_RECORD_LAYER_set_write_sequence(RECORD_LAYER *rl, unsigned char *seq) +{ + memcpy(rl->write_sequence, seq, SEQ_NUM_SIZE); +} + static int have_handshake_fragment(SSL *s, int type, unsigned char *buf, int len, int peek); @@ -268,14 +264,11 @@ int dtls1_buffer_record(SSL *s, record_pqueue *queue, unsigned char *priority) if (pqueue_size(queue->q) >= 100) return 0; - rdata = OPENSSL_malloc(sizeof(DTLS1_RECORD_DATA)); + rdata = OPENSSL_malloc(sizeof(*rdata)); item = pitem_new(priority, rdata); if (rdata == NULL || item == NULL) { - if (rdata != NULL) - OPENSSL_free(rdata); - if (item != NULL) - pitem_free(item); - + OPENSSL_free(rdata); + pitem_free(item); SSLerr(SSL_F_DTLS1_BUFFER_RECORD, ERR_R_INTERNAL_ERROR); return -1; } @@ -299,13 +292,12 @@ int dtls1_buffer_record(SSL *s, record_pqueue *queue, unsigned char *priority) s->rlayer.packet = NULL; s->rlayer.packet_length = 0; - memset(&s->rlayer.rbuf, 0, sizeof(SSL3_BUFFER)); - memset(&s->rlayer.rrec, 0, sizeof(SSL3_RECORD)); + memset(&s->rlayer.rbuf, 0, sizeof(s->rlayer.rbuf)); + memset(&s->rlayer.rrec, 0, sizeof(s->rlayer.rrec)); if (!ssl3_setup_buffers(s)) { SSLerr(SSL_F_DTLS1_BUFFER_RECORD, ERR_R_INTERNAL_ERROR); - if (rdata->rbuf.buf != NULL) - OPENSSL_free(rdata->rbuf.buf); + OPENSSL_free(rdata->rbuf.buf); OPENSSL_free(rdata); pitem_free(item); return (-1); @@ -314,8 +306,7 @@ int dtls1_buffer_record(SSL *s, record_pqueue *queue, unsigned char *priority) /* insert should not fail, since duplicates are dropped */ if (pqueue_insert(queue->q, item) == NULL) { SSLerr(SSL_F_DTLS1_BUFFER_RECORD, ERR_R_INTERNAL_ERROR); - if (rdata->rbuf.buf != NULL) - OPENSSL_free(rdata->rbuf.buf); + OPENSSL_free(rdata->rbuf.buf); OPENSSL_free(rdata); pitem_free(item); return (-1); @@ -394,8 +385,9 @@ int dtls1_process_buffered_records(SSL *s) * (possibly multiple records if we still don't have anything to return). * * This function must handle any surprises the peer may have for us, such as - * Alert records (e.g. close_notify), ChangeCipherSpec records (not really - * a surprise, but handled as if it were), or renegotiation requests. + * Alert records (e.g. close_notify) or renegotiation requests. ChangeCipherSpec + * messages are treated as if they were handshake messages *if* the |recd_type| + * argument is non NULL. * Also if record payloads contain fragments too small to process, we store * them until there is enough for the respective protocol (the record protocol * may use arbitrary fragmentation and even interleaving): @@ -410,7 +402,8 @@ int dtls1_process_buffered_records(SSL *s) * Application data protocol * none of our business */ -int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) +int dtls1_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, + int len, int peek) { int al, i, j, ret; unsigned int n; @@ -447,9 +440,8 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) * SCTP. */ if ((!s->in_handshake && SSL_in_init(s)) || - (BIO_dgram_is_sctp(SSL_get_rbio(s)) && - (s->state == DTLS1_SCTP_ST_SR_READ_SOCK - || s->state == DTLS1_SCTP_ST_CR_READ_SOCK) + (BIO_dgram_is_sctp(SSL_get_rbio(s)) + && statem_in_sctp_read_sock(s) && s->s3->in_read_app_data != 2)) #else if (!s->in_handshake && SSL_in_init(s)) @@ -518,11 +510,6 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) } } - if (s->d1->listen && rr->type != SSL3_RT_HANDSHAKE) { - SSL3_RECORD_set_length(rr, 0); - goto start; - } - /* we now have a packet which can be read and processed */ if (s->s3->change_cipher_spec /* set when we receive ChangeCipherSpec, @@ -552,9 +539,14 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) return (0); } - if (type == SSL3_RECORD_get_type(rr)) { - /* SSL3_RT_APPLICATION_DATA or - * SSL3_RT_HANDSHAKE */ + if (type == SSL3_RECORD_get_type(rr) + || (SSL3_RECORD_get_type(rr) == SSL3_RT_CHANGE_CIPHER_SPEC + && type == SSL3_RT_HANDSHAKE && recvd_type != NULL)) { + /* + * SSL3_RT_APPLICATION_DATA or + * SSL3_RT_HANDSHAKE or + * SSL3_RT_CHANGE_CIPHER_SPEC + */ /* * make sure that we are not getting application data when we are * doing a handshake for the first time @@ -566,6 +558,9 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) goto f_err; } + if (recvd_type != NULL) + *recvd_type = SSL3_RECORD_get_type(rr); + if (len <= 0) return (len); @@ -590,8 +585,7 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) */ if (BIO_dgram_is_sctp(SSL_get_rbio(s)) && SSL3_RECORD_get_type(rr) == SSL3_RT_APPLICATION_DATA && - (s->state == DTLS1_SCTP_ST_SR_READ_SOCK - || s->state == DTLS1_SCTP_ST_CR_READ_SOCK)) { + statem_in_sctp_read_sock(s)) { s->rwstate = SSL_READING; BIO_clear_retry_flags(SSL_get_rbio(s)); BIO_set_retry_read(SSL_get_rbio(s)); @@ -638,7 +632,7 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) #ifndef OPENSSL_NO_HEARTBEATS else if (SSL3_RECORD_get_type(rr) == TLS1_RT_HEARTBEAT) { /* We allow a 0 return */ - if(dtls1_process_heartbeat(s, SSL3_RECORD_get_data(rr), + if (dtls1_process_heartbeat(s, SSL3_RECORD_get_data(rr), SSL3_RECORD_get_length(rr)) < 0) { return -1; } @@ -719,7 +713,7 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) (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; + goto f_err; } /* @@ -872,62 +866,11 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) } if (SSL3_RECORD_get_type(rr) == SSL3_RT_CHANGE_CIPHER_SPEC) { - struct ccs_header_st ccs_hdr; - unsigned int ccs_hdr_len = DTLS1_CCS_HEADER_LENGTH; - - dtls1_get_ccs_header(SSL3_RECORD_get_data(rr), &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 ((SSL3_RECORD_get_length(rr) != ccs_hdr_len) - || (SSL3_RECORD_get_off(rr) != 0) - || (SSL3_RECORD_get_data(rr)[0] != SSL3_MT_CCS)) { - i = SSL_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_BAD_CHANGE_CIPHER_SPEC); - goto err; - } - - SSL3_RECORD_set_length(rr, 0); - - if (s->msg_callback) - s->msg_callback(0, s->version, SSL3_RT_CHANGE_CIPHER_SPEC, - SSL3_RECORD_get_data(rr), 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++; - -#ifndef OPENSSL_NO_SCTP - /* - * Remember that a CCS has been received, so that an old key of - * SCTP-Auth can be deleted when a CCS is sent. Will be ignored if no - * SCTP is used - */ - BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD, 1, NULL); -#endif - + SSL3_RECORD_set_length(rr, 0); goto start; } @@ -1043,7 +986,6 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) f_err: ssl3_send_alert(s, SSL3_AL_FATAL, al); - err: return (-1); } @@ -1177,6 +1119,8 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf, /* Need explicit part of IV for GCM mode */ else if (mode == EVP_CIPH_GCM_MODE) eivlen = EVP_GCM_TLS_EXPLICIT_IV_LEN; + else if (mode == EVP_CIPH_CCM_MODE) + eivlen = EVP_CCM_TLS_EXPLICIT_IV_LEN; else eivlen = 0; } else @@ -1313,9 +1257,10 @@ void dtls1_reset_seq_numbers(SSL *s, int rw) if (rw & SSL3_CC_READ) { seq = s->rlayer.read_sequence; 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)); + memcpy(&s->rlayer.d->bitmap, &s->rlayer.d->next_bitmap, + sizeof(s->rlayer.d->bitmap)); + memset(&s->rlayer.d->next_bitmap, 0, + sizeof(s->rlayer.d->next_bitmap)); } else { seq = s->rlayer.write_sequence; memcpy(s->rlayer.d->last_write_sequence, seq, @@ -1323,5 +1268,5 @@ void dtls1_reset_seq_numbers(SSL *s, int rw) s->rlayer.d->w_epoch++; } - memset(seq, 0x00, seq_bytes); + memset(seq, 0, seq_bytes); }