X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=ssl%2Frecord%2Frec_layer_d1.c;h=f9bf10963cf5fda77e4fdbc685cce9a747cee598;hp=c58af7f36abeefa282337798721e6234440bdcf8;hb=a230b26e0959dc5f072fbbdadcc9ed45e904c50c;hpb=747e16398d704a667cc99f8a0b1912c36b7de52d diff --git a/ssl/record/rec_layer_d1.c b/ssl/record/rec_layer_d1.c index c58af7f36a..f9bf10963c 100644 --- a/ssl/record/rec_layer_d1.c +++ b/ssl/record/rec_layer_d1.c @@ -1,116 +1,10 @@ -/* ssl/record/rec_layer_d1.c */ /* - * DTLS implementation written by Nagendra Modadugu - * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. - */ -/* ==================================================================== - * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). + * Copyright 2005-2016 The OpenSSL Project Authors. All Rights Reserved. * - */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html */ #include @@ -119,18 +13,14 @@ #include "../ssl_locl.h" #include #include -#include -#include #include "record_locl.h" int DTLS_RECORD_LAYER_new(RECORD_LAYER *rl) { DTLS_RECORD_LAYER *d; - - if ((d = OPENSSL_malloc(sizeof *d)) == NULL) { - return (0); - } + if ((d = OPENSSL_malloc(sizeof(*d))) == NULL) + return (0); rl->d = d; @@ -138,14 +28,11 @@ int DTLS_RECORD_LAYER_new(RECORD_LAYER *rl) 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); + if (d->unprocessed_rcds.q == NULL || d->processed_rcds.q == NULL + || d->buffered_app_data.q == NULL) { + 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); @@ -169,35 +56,29 @@ 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; + pqueue *unprocessed_rcds; + pqueue *processed_rcds; + pqueue *buffered_app_data; d = rl->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(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 +86,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; @@ -215,18 +96,14 @@ void DTLS_RECORD_LAYER_set_saved_w_epoch(RECORD_LAYER *rl, unsigned short e) { if (e == rl->d->w_epoch - 1) { memcpy(rl->d->curr_write_sequence, - rl->write_sequence, - sizeof(rl->write_sequence)); + rl->write_sequence, sizeof(rl->write_sequence)); memcpy(rl->write_sequence, - rl->d->last_write_sequence, - sizeof(rl->write_sequence)); + rl->d->last_write_sequence, sizeof(rl->write_sequence)); } else if (e == rl->d->w_epoch + 1) { memcpy(rl->d->last_write_sequence, - rl->write_sequence, - sizeof(unsigned char[8])); + rl->write_sequence, sizeof(unsigned char[8])); memcpy(rl->write_sequence, - rl->d->curr_write_sequence, - sizeof(rl->write_sequence)); + rl->d->curr_write_sequence, sizeof(rl->write_sequence)); } rl->d->w_epoch = e; } @@ -236,8 +113,13 @@ 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); + int len); /* copy buffered record into SSL structure */ static int dtls1_copy_record(SSL *s, pitem *item) @@ -268,14 +150,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; } @@ -290,8 +169,8 @@ int dtls1_buffer_record(SSL *s, record_pqueue *queue, unsigned char *priority) #ifndef OPENSSL_NO_SCTP /* Store bio_dgram_sctp_rcvinfo struct */ if (BIO_dgram_is_sctp(SSL_get_rbio(s)) && - (s->state == SSL3_ST_SR_FINISHED_A - || s->state == SSL3_ST_CR_FINISHED_A)) { + (SSL_get_state(s) == TLS_ST_SR_FINISHED + || SSL_get_state(s) == TLS_ST_CR_FINISHED)) { BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SCTP_GET_RCVINFO, sizeof(rdata->recordinfo), &rdata->recordinfo); } @@ -299,13 +178,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 +192,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); @@ -349,7 +226,6 @@ int dtls1_retrieve_buffered_record(SSL *s, record_pqueue *queue) dtls1_retrieve_buffered_record((s), \ &((s)->rlayer.d->unprocessed_rcds)) - int dtls1_process_buffered_records(SSL *s) { pitem *item; @@ -366,7 +242,8 @@ int dtls1_process_buffered_records(SSL *s) if (!dtls1_process_record(s)) return (0); if (dtls1_buffer_record(s, &(s->rlayer.d->processed_rcds), - SSL3_RECORD_get_seq_num(&s->rlayer.rrec)) < 0) + SSL3_RECORD_get_seq_num(s->rlayer.rrec)) < + 0) return -1; } } @@ -381,7 +258,6 @@ int dtls1_process_buffered_records(SSL *s) return (1); } - /*- * Return up to 'len' payload bytes received in 'type' records. * 'type' is one of the following: @@ -394,8 +270,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 +287,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; @@ -433,7 +311,7 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) /* * check whether there's a handshake message (client hello?) waiting */ - if ((ret = have_handshake_fragment(s, type, buf, len, peek))) + if ((ret = have_handshake_fragment(s, type, buf, len))) return ret; /* @@ -446,13 +324,12 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) * Continue handshake if it had to be interrupted to read app data with * 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) + if ((!ossl_statem_get_in_handshake(s) && SSL_in_init(s)) || + (BIO_dgram_is_sctp(SSL_get_rbio(s)) + && ossl_statem_in_sctp_read_sock(s) && s->s3->in_read_app_data != 2)) #else - if (!s->in_handshake && SSL_in_init(s)) + if (!ossl_statem_get_in_handshake(s) && SSL_in_init(s)) #endif { /* type == SSL3_RT_APPLICATION_DATA */ @@ -474,13 +351,13 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) * s->s3->rrec.off, - offset into 'data' for next read * s->s3->rrec.length, - number of bytes. */ - rr = &s->rlayer.rrec; + rr = s->rlayer.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 && SSL3_RECORD_get_length(rr) == 0) { + if (SSL_is_init_finished(s) && SSL3_RECORD_get_length(rr) == 0) { pitem *item; item = pqueue_pop(s->rlayer.d->buffered_app_data.q); if (item) { @@ -506,7 +383,7 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) /* get new packet if necessary */ if ((SSL3_RECORD_get_length(rr) == 0) - || (s->rlayer.rstate == SSL_ST_READ_BODY)) { + || (s->rlayer.rstate == SSL_ST_READ_BODY)) { ret = dtls1_get_record(s); if (ret <= 0) { ret = dtls1_read_failed(s, ret); @@ -518,11 +395,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, @@ -534,7 +406,7 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) * data for later processing rather than dropping the connection. */ if (dtls1_buffer_record(s, &(s->rlayer.d->buffered_app_data), - SSL3_RECORD_get_seq_num(rr)) < 0) { + SSL3_RECORD_get_seq_num(rr)) < 0) { SSLerr(SSL_F_DTLS1_READ_BYTES, ERR_R_INTERNAL_ERROR); return -1; } @@ -552,9 +424,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 +443,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); @@ -576,7 +456,7 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) memcpy(buf, &(SSL3_RECORD_get_data(rr)[SSL3_RECORD_get_off(rr)]), n); if (!peek) { - SSL3_RECORD_add_length(rr, -n); + SSL3_RECORD_sub_length(rr, n); SSL3_RECORD_add_off(rr, n); if (SSL3_RECORD_get_length(rr) == 0) { s->rlayer.rstate = SSL_ST_READ_HEADER; @@ -590,8 +470,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)) { + ossl_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)); @@ -636,10 +515,10 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) dest_len = &s->rlayer.d->alert_fragment_len; } #ifndef OPENSSL_NO_HEARTBEATS - else if (SSL3_RECORD_get_type(rr) == TLS1_RT_HEARTBEAT) { + else if (SSL3_RECORD_get_type(rr) == DTLS1_RT_HEARTBEAT) { /* We allow a 0 return */ - if(dtls1_process_heartbeat(s, SSL3_RECORD_get_data(rr), - SSL3_RECORD_get_length(rr)) < 0) { + if (dtls1_process_heartbeat(s, SSL3_RECORD_get_data(rr), + SSL3_RECORD_get_length(rr)) < 0) { return -1; } /* Exit and notify application to read again */ @@ -656,7 +535,7 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) * Application data while renegotiating is allowed. Try again * reading. */ - if (SSL3_RECORD_get_type(rr) == SSL3_RT_APPLICATION_DATA) { + if (SSL3_RECORD_get_type(rr) == SSL3_RT_APPLICATION_DATA) { BIO *bio; s->s3->in_read_app_data = 2; bio = SSL_get_rbio(s); @@ -674,17 +553,17 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) if (dest_maxlen > 0) { /* - * XDTLS: In a pathalogical case, the Client Hello may be + * XDTLS: In a pathological case, the Client Hello may be * fragmented--don't always expect dest_maxlen bytes */ - if (SSL3_RECORD_get_length(rr) < dest_maxlen) { + if (SSL3_RECORD_get_length(rr) < dest_maxlen) { #ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE /* * for normal alerts rr->length is 2, while * dest_maxlen is 7 if we were to handle this * non-existing alert... */ - FIX ME + FIX ME; #endif s->rlayer.rstate = SSL_ST_READ_HEADER; SSL3_RECORD_set_length(rr, 0); @@ -719,7 +598,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; } /* @@ -742,8 +621,7 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) if (i < 0) return (i); if (i == 0) { - SSLerr(SSL_F_DTLS1_READ_BYTES, - SSL_R_SSL_HANDSHAKE_FAILURE); + SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_SSL_HANDSHAKE_FAILURE); return (-1); } @@ -848,12 +726,11 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) s->rwstate = SSL_NOTHING; s->s3->fatal_alert = alert_descr; - SSLerr(SSL_F_DTLS1_READ_BYTES, - SSL_AD_REASON_OFFSET + alert_descr); + SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_AD_REASON_OFFSET + alert_descr); BIO_snprintf(tmp, sizeof tmp, "%d", alert_descr); ERR_add_error_data(2, "SSL alert number ", tmp); s->shutdown |= SSL_RECEIVED_SHUTDOWN; - SSL_CTX_remove_session(s->ctx, s->session); + SSL_CTX_remove_session(s->session_ctx, s->session); return (0); } else { al = SSL_AD_ILLEGAL_PARAMETER; @@ -872,62 +749,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; } @@ -935,7 +761,7 @@ 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->rlayer.d->handshake_fragment_len >= DTLS1_HM_HEADER_LENGTH) && - !s->in_handshake) { + !ossl_statem_get_in_handshake(s)) { struct hm_header_st msg_hdr; /* this may just be a stale retransmit */ @@ -958,9 +784,9 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) goto start; } - if (((s->state & SSL_ST_MASK) == SSL_ST_OK) && + if (SSL_is_init_finished(s) && !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS)) { - s->state = s->server ? SSL_ST_ACCEPT : SSL_ST_CONNECT; + ossl_statem_set_in_init(s, 1); s->renegotiate = 1; s->new_session = 1; } @@ -1007,8 +833,8 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) case SSL3_RT_HANDSHAKE: /* * we already handled all of these, with the possible exception of - * SSL3_RT_HANDSHAKE when s->in_handshake is set, but that should not - * happen when type != rr->type + * SSL3_RT_HANDSHAKE when ossl_statem_get_in_handshake(s) is true, but + * that should not happen when type != rr->type */ al = SSL_AD_UNEXPECTED_MESSAGE; SSLerr(SSL_F_DTLS1_READ_BYTES, ERR_R_INTERNAL_ERROR); @@ -1023,14 +849,7 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) */ if (s->s3->in_read_app_data && (s->s3->total_renegotiations != 0) && - (((s->state & SSL_ST_CONNECT) && - (s->state >= SSL3_ST_CW_CLNT_HELLO_A) && - (s->state <= SSL3_ST_CR_SRVR_HELLO_A) - ) || ((s->state & SSL_ST_ACCEPT) && - (s->state <= SSL3_ST_SW_HELLO_REQ_A) && - (s->state >= SSL3_ST_SR_CLNT_HELLO_A) - ) - )) { + ossl_statem_app_data_allowed(s)) { s->s3->in_read_app_data = 2; return (-1); } else { @@ -1043,21 +862,19 @@ 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); } - /* * this only happens when a client hello is received and a handshake * is started. */ static int have_handshake_fragment(SSL *s, int type, unsigned char *buf, - int len, int peek) + int len) { if ((type == SSL3_RT_HANDSHAKE) - && (s->rlayer.d->handshake_fragment_len > 0)) + && (s->rlayer.d->handshake_fragment_len > 0)) /* (partially) satisfy request from storage */ { unsigned char *src = s->rlayer.d->handshake_fragment; @@ -1102,11 +919,11 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf, int i, mac_size, clear = 0; int prefix_len = 0; int eivlen; - SSL3_RECORD *wr; + SSL3_RECORD wr; SSL3_BUFFER *wb; SSL_SESSION *sess; - wb = &s->rlayer.wbuf; + wb = &s->rlayer.wbuf[0]; /* * first check if there is a SSL3_BUFFER still being written out. This @@ -1128,7 +945,6 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf, if (len == 0 && !create_empty_fragment) return 0; - wr = &s->rlayer.wrec; sess = s->session; if ((sess == NULL) || @@ -1148,13 +964,14 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf, /* write the header */ *(p++) = type & 0xff; - SSL3_RECORD_set_type(wr, type); + SSL3_RECORD_set_type(&wr, type); /* * Special case: for hello verify request, client version 1.0 and we * haven't decided which version to use yet send back using version 1.0 * header: otherwise some clients will ignore it. */ - if (s->method->version == DTLS_ANY_VERSION) { + if (s->method->version == DTLS_ANY_VERSION && + s->max_proto_version != DTLS1_BAD_VER) { *(p++) = DTLS1_VERSION >> 8; *(p++) = DTLS1_VERSION & 0xff; } else { @@ -1177,53 +994,56 @@ 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 eivlen = 0; /* lets setup the record stuff. */ - SSL3_RECORD_set_data(wr, p + eivlen); /* make room for IV in case of CBC */ - SSL3_RECORD_set_length(wr, (int)len); - SSL3_RECORD_set_input(wr, (unsigned char *)buf); + SSL3_RECORD_set_data(&wr, p + eivlen); /* make room for IV in case of CBC */ + SSL3_RECORD_set_length(&wr, (int)len); + SSL3_RECORD_set_input(&wr, (unsigned char *)buf); /* - * we now 'read' from wr->input, wr->length bytes into wr->data + * we now 'read' from wr.input, wr.length bytes into wr.data */ /* first we compress */ if (s->compress != NULL) { - if (!ssl3_do_compress(s)) { + if (!ssl3_do_compress(s, &wr)) { SSLerr(SSL_F_DO_DTLS1_WRITE, SSL_R_COMPRESSION_FAILURE); goto err; } } else { - memcpy(SSL3_RECORD_get_data(wr), SSL3_RECORD_get_input(wr), - SSL3_RECORD_get_length(wr)); - SSL3_RECORD_reset_input(wr); + memcpy(SSL3_RECORD_get_data(&wr), SSL3_RECORD_get_input(&wr), + SSL3_RECORD_get_length(&wr)); + SSL3_RECORD_reset_input(&wr); } /* - * we should still have the output to wr->data and the input from - * wr->input. Length should be wr->length. wr->data still points in the + * we should still have the output to wr.data and the input from + * wr.input. Length should be wr.length. wr.data still points in the * wb->buf */ if (mac_size != 0) { - if (s->method->ssl3_enc->mac(s, - &(p[SSL3_RECORD_get_length(wr) + eivlen]), 1) < 0) + if (s->method->ssl3_enc->mac(s, &wr, + &(p[SSL3_RECORD_get_length(&wr) + eivlen]), + 1) < 0) goto err; - SSL3_RECORD_add_length(wr, mac_size); + SSL3_RECORD_add_length(&wr, mac_size); } /* this is true regardless of mac size */ - SSL3_RECORD_set_data(wr, p); - SSL3_RECORD_reset_input(wr); + SSL3_RECORD_set_data(&wr, p); + SSL3_RECORD_reset_input(&wr); if (eivlen) - SSL3_RECORD_add_length(wr, eivlen); + SSL3_RECORD_add_length(&wr, eivlen); - if (s->method->ssl3_enc->enc(s, 1) < 1) + if (s->method->ssl3_enc->enc(s, &wr, 1, 1) < 1) goto err; /* record length after mac and block padding */ @@ -1243,18 +1063,18 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf, memcpy(pseq, &(s->rlayer.write_sequence[2]), 6); pseq += 6; - s2n(SSL3_RECORD_get_length(wr), pseq); + s2n(SSL3_RECORD_get_length(&wr), pseq); if (s->msg_callback) s->msg_callback(1, 0, SSL3_RT_HEADER, pseq - DTLS1_RT_HEADER_LENGTH, DTLS1_RT_HEADER_LENGTH, s, s->msg_callback_arg); /* - * we should now have wr->data pointing to the encrypted data, which is + * we should now have wr.data pointing to the encrypted data, which is * wr->length long */ - SSL3_RECORD_set_type(wr, type); /* not needed but helps for debugging */ - SSL3_RECORD_add_length(wr, DTLS1_RT_HEADER_LENGTH); + SSL3_RECORD_set_type(&wr, type); /* not needed but helps for debugging */ + SSL3_RECORD_add_length(&wr, DTLS1_RT_HEADER_LENGTH); ssl3_record_sequence_update(&(s->rlayer.write_sequence[0])); @@ -1263,11 +1083,11 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf, * we are in a recursive call; just return the length, don't write * out anything here */ - return wr->length; + return wr.length; } /* now let's set up wb */ - SSL3_BUFFER_set_left(wb, prefix_len + SSL3_RECORD_get_length(wr)); + SSL3_BUFFER_set_left(wb, prefix_len + SSL3_RECORD_get_length(&wr)); SSL3_BUFFER_set_offset(wb, 0); /* @@ -1286,7 +1106,7 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf, } DTLS1_BITMAP *dtls1_get_bitmap(SSL *s, SSL3_RECORD *rr, - unsigned int *is_next_epoch) + unsigned int *is_next_epoch) { *is_next_epoch = 0; @@ -1297,7 +1117,7 @@ DTLS1_BITMAP *dtls1_get_bitmap(SSL *s, SSL3_RECORD *rr, /* Only HM and ALERT messages can be from the next epoch */ else if (rr->epoch == (unsigned long)(s->rlayer.d->r_epoch + 1) && - (rr->type == SSL3_RT_HANDSHAKE || rr->type == SSL3_RT_ALERT)) { + (rr->type == SSL3_RT_HANDSHAKE || rr->type == SSL3_RT_ALERT)) { *is_next_epoch = 1; return &s->rlayer.d->next_bitmap; } @@ -1313,9 +1133,9 @@ 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 +1143,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); }