Commit 747e1639 authored by Matt Caswell's avatar Matt Caswell
Browse files

Clean up record layer



Fix up various things that were missed during the record layer work. All
instances where we are breaking the encapsulation rules.

Reviewed-by: default avatarRichard Levitte <levitte@openssl.org>
parent 1b34e25c
Loading
Loading
Loading
Loading
+65 −59
Original line number Original line Diff line number Diff line
@@ -480,7 +480,7 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
     * We are not handshaking and have no data yet, so process data buffered
     * We are not handshaking and have no data yet, so process data buffered
     * during the last handshake in advance, if any.
     * during the last handshake in advance, if any.
     */
     */
    if (s->state == SSL_ST_OK && rr->length == 0) {
    if (s->state == SSL_ST_OK && SSL3_RECORD_get_length(rr) == 0) {
        pitem *item;
        pitem *item;
        item = pqueue_pop(s->rlayer.d->buffered_app_data.q);
        item = pqueue_pop(s->rlayer.d->buffered_app_data.q);
        if (item) {
        if (item) {
@@ -505,7 +505,8 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
        goto start;
        goto start;


    /* get new packet if necessary */
    /* get new packet if necessary */
    if ((rr->length == 0) || (s->rlayer.rstate == SSL_ST_READ_BODY)) {
    if ((SSL3_RECORD_get_length(rr) == 0)
            || (s->rlayer.rstate == SSL_ST_READ_BODY)) {
        ret = dtls1_get_record(s);
        ret = dtls1_get_record(s);
        if (ret <= 0) {
        if (ret <= 0) {
            ret = dtls1_read_failed(s, ret);
            ret = dtls1_read_failed(s, ret);
@@ -518,7 +519,7 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
    }
    }


    if (s->d1->listen && rr->type != SSL3_RT_HANDSHAKE) {
    if (s->d1->listen && rr->type != SSL3_RT_HANDSHAKE) {
        rr->length = 0;
        SSL3_RECORD_set_length(rr, 0);
        goto start;
        goto start;
    }
    }


@@ -526,18 +527,18 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)


    if (s->s3->change_cipher_spec /* set when we receive ChangeCipherSpec,
    if (s->s3->change_cipher_spec /* set when we receive ChangeCipherSpec,
                                   * reset by ssl3_get_finished */
                                   * reset by ssl3_get_finished */
        && (rr->type != SSL3_RT_HANDSHAKE)) {
        && (SSL3_RECORD_get_type(rr) != SSL3_RT_HANDSHAKE)) {
        /*
        /*
         * We now have application data between CCS and Finished. Most likely
         * We now have application data between CCS and Finished. Most likely
         * the packets were reordered on their way, so buffer the application
         * the packets were reordered on their way, so buffer the application
         * data for later processing rather than dropping the connection.
         * data for later processing rather than dropping the connection.
         */
         */
        if (dtls1_buffer_record(s, &(s->rlayer.d->buffered_app_data),
        if (dtls1_buffer_record(s, &(s->rlayer.d->buffered_app_data),
            rr->seq_num) < 0) {
            SSL3_RECORD_get_seq_num(rr)) < 0) {
            SSLerr(SSL_F_DTLS1_READ_BYTES, ERR_R_INTERNAL_ERROR);
            SSLerr(SSL_F_DTLS1_READ_BYTES, ERR_R_INTERNAL_ERROR);
            return -1;
            return -1;
        }
        }
        rr->length = 0;
        SSL3_RECORD_set_length(rr, 0);
        goto start;
        goto start;
    }
    }


@@ -546,12 +547,13 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
     * 'peek' mode)
     * 'peek' mode)
     */
     */
    if (s->shutdown & SSL_RECEIVED_SHUTDOWN) {
    if (s->shutdown & SSL_RECEIVED_SHUTDOWN) {
        rr->length = 0;
        SSL3_RECORD_set_length(rr, 0);
        s->rwstate = SSL_NOTHING;
        s->rwstate = SSL_NOTHING;
        return (0);
        return (0);
    }
    }


    if (type == rr->type) {     /* SSL3_RT_APPLICATION_DATA or
    if (type == SSL3_RECORD_get_type(rr)) {
        /* SSL3_RT_APPLICATION_DATA or
         * SSL3_RT_HANDSHAKE */
         * SSL3_RT_HANDSHAKE */
        /*
        /*
         * make sure that we are not getting application data when we are
         * make sure that we are not getting application data when we are
@@ -567,18 +569,18 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
        if (len <= 0)
        if (len <= 0)
            return (len);
            return (len);


        if ((unsigned int)len > rr->length)
        if ((unsigned int)len > SSL3_RECORD_get_length(rr))
            n = rr->length;
            n = SSL3_RECORD_get_length(rr);
        else
        else
            n = (unsigned int)len;
            n = (unsigned int)len;


        memcpy(buf, &(rr->data[rr->off]), n);
        memcpy(buf, &(SSL3_RECORD_get_data(rr)[SSL3_RECORD_get_off(rr)]), n);
        if (!peek) {
        if (!peek) {
            rr->length -= n;
            SSL3_RECORD_add_length(rr, -n);
            rr->off += n;
            SSL3_RECORD_add_off(rr, n);
            if (rr->length == 0) {
            if (SSL3_RECORD_get_length(rr) == 0) {
                s->rlayer.rstate = SSL_ST_READ_HEADER;
                s->rlayer.rstate = SSL_ST_READ_HEADER;
                rr->off = 0;
                SSL3_RECORD_set_off(rr, 0);
            }
            }
        }
        }
#ifndef OPENSSL_NO_SCTP
#ifndef OPENSSL_NO_SCTP
@@ -587,7 +589,7 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
         * data first, so retry.
         * data first, so retry.
         */
         */
        if (BIO_dgram_is_sctp(SSL_get_rbio(s)) &&
        if (BIO_dgram_is_sctp(SSL_get_rbio(s)) &&
            rr->type == SSL3_RT_APPLICATION_DATA &&
            SSL3_RECORD_get_type(rr) == SSL3_RT_APPLICATION_DATA &&
            (s->state == DTLS1_SCTP_ST_SR_READ_SOCK
            (s->state == DTLS1_SCTP_ST_SR_READ_SOCK
             || s->state == DTLS1_SCTP_ST_CR_READ_SOCK)) {
             || s->state == DTLS1_SCTP_ST_CR_READ_SOCK)) {
            s->rwstate = SSL_READING;
            s->rwstate = SSL_READING;
@@ -624,24 +626,24 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
        unsigned char *dest = NULL;
        unsigned char *dest = NULL;
        unsigned int *dest_len = NULL;
        unsigned int *dest_len = NULL;


        if (rr->type == SSL3_RT_HANDSHAKE) {
        if (SSL3_RECORD_get_type(rr) == SSL3_RT_HANDSHAKE) {
            dest_maxlen = sizeof s->rlayer.d->handshake_fragment;
            dest_maxlen = sizeof s->rlayer.d->handshake_fragment;
            dest = s->rlayer.d->handshake_fragment;
            dest = s->rlayer.d->handshake_fragment;
            dest_len = &s->rlayer.d->handshake_fragment_len;
            dest_len = &s->rlayer.d->handshake_fragment_len;
        } else if (rr->type == SSL3_RT_ALERT) {
        } else if (SSL3_RECORD_get_type(rr) == SSL3_RT_ALERT) {
            dest_maxlen = sizeof(s->rlayer.d->alert_fragment);
            dest_maxlen = sizeof(s->rlayer.d->alert_fragment);
            dest = s->rlayer.d->alert_fragment;
            dest = s->rlayer.d->alert_fragment;
            dest_len = &s->rlayer.d->alert_fragment_len;
            dest_len = &s->rlayer.d->alert_fragment_len;
        }
        }
#ifndef OPENSSL_NO_HEARTBEATS
#ifndef OPENSSL_NO_HEARTBEATS
        else if (rr->type == TLS1_RT_HEARTBEAT) {
        else if (SSL3_RECORD_get_type(rr) == TLS1_RT_HEARTBEAT) {
            /* We allow a 0 return */
            /* We allow a 0 return */
            if(dtls1_process_heartbeat(s, SSL3_RECORD_get_data(&s->rlayer.rrec),
            if(dtls1_process_heartbeat(s, SSL3_RECORD_get_data(rr),
                    SSL3_RECORD_get_length(&s->rlayer.rrec)) < 0) {
                    SSL3_RECORD_get_length(rr)) < 0) {
                return -1;
                return -1;
            }
            }
            /* Exit and notify application to read again */
            /* Exit and notify application to read again */
            rr->length = 0;
            SSL3_RECORD_set_length(rr, 0);
            s->rwstate = SSL_READING;
            s->rwstate = SSL_READING;
            BIO_clear_retry_flags(SSL_get_rbio(s));
            BIO_clear_retry_flags(SSL_get_rbio(s));
            BIO_set_retry_read(SSL_get_rbio(s));
            BIO_set_retry_read(SSL_get_rbio(s));
@@ -649,12 +651,12 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
        }
        }
#endif
#endif
        /* else it's a CCS message, or application data or wrong */
        /* else it's a CCS message, or application data or wrong */
        else if (rr->type != SSL3_RT_CHANGE_CIPHER_SPEC) {
        else if (SSL3_RECORD_get_type(rr) != SSL3_RT_CHANGE_CIPHER_SPEC) {
            /*
            /*
             * Application data while renegotiating is allowed. Try again
             * Application data while renegotiating is allowed. Try again
             * reading.
             * reading.
             */
             */
            if (rr->type == SSL3_RT_APPLICATION_DATA) {
            if (SSL3_RECORD_get_type(rr)  == SSL3_RT_APPLICATION_DATA) {
                BIO *bio;
                BIO *bio;
                s->s3->in_read_app_data = 2;
                s->s3->in_read_app_data = 2;
                bio = SSL_get_rbio(s);
                bio = SSL_get_rbio(s);
@@ -675,7 +677,7 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
             * XDTLS: In a pathalogical case, the Client Hello may be
             * XDTLS: In a pathalogical case, the Client Hello may be
             * fragmented--don't always expect dest_maxlen bytes
             * fragmented--don't always expect dest_maxlen bytes
             */
             */
            if (rr->length < dest_maxlen) {
            if (SSL3_RECORD_get_length(rr)  < dest_maxlen) {
#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE
#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE
                /*
                /*
                 * for normal alerts rr->length is 2, while
                 * for normal alerts rr->length is 2, while
@@ -685,14 +687,15 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
                FIX ME
                FIX ME
#endif
#endif
                s->rlayer.rstate = SSL_ST_READ_HEADER;
                s->rlayer.rstate = SSL_ST_READ_HEADER;
                rr->length = 0;
                SSL3_RECORD_set_length(rr, 0);
                goto start;
                goto start;
            }
            }


            /* now move 'n' bytes: */
            /* now move 'n' bytes: */
            for (k = 0; k < dest_maxlen; k++) {
            for (k = 0; k < dest_maxlen; k++) {
                dest[k] = rr->data[rr->off++];
                dest[k] = SSL3_RECORD_get_data(rr)[SSL3_RECORD_get_off(rr)];
                rr->length--;
                SSL3_RECORD_add_off(rr, 1);
                SSL3_RECORD_add_length(rr, -1);
            }
            }
            *dest_len = dest_maxlen;
            *dest_len = dest_maxlen;
        }
        }
@@ -864,15 +867,15 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
    if (s->shutdown & SSL_SENT_SHUTDOWN) { /* but we have not received a
    if (s->shutdown & SSL_SENT_SHUTDOWN) { /* but we have not received a
                                            * shutdown */
                                            * shutdown */
        s->rwstate = SSL_NOTHING;
        s->rwstate = SSL_NOTHING;
        rr->length = 0;
        SSL3_RECORD_set_length(rr, 0);
        return (0);
        return (0);
    }
    }


    if (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC) {
    if (SSL3_RECORD_get_type(rr) == SSL3_RT_CHANGE_CIPHER_SPEC) {
        struct ccs_header_st ccs_hdr;
        struct ccs_header_st ccs_hdr;
        unsigned int ccs_hdr_len = DTLS1_CCS_HEADER_LENGTH;
        unsigned int ccs_hdr_len = DTLS1_CCS_HEADER_LENGTH;


        dtls1_get_ccs_header(rr->data, &ccs_hdr);
        dtls1_get_ccs_header(SSL3_RECORD_get_data(rr), &ccs_hdr);


        if (s->version == DTLS1_BAD_VER)
        if (s->version == DTLS1_BAD_VER)
            ccs_hdr_len = 3;
            ccs_hdr_len = 3;
@@ -882,18 +885,19 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
         * what the record payload has to look like
         * what the record payload has to look like
         */
         */
        /* XDTLS: check that epoch is consistent */
        /* XDTLS: check that epoch is consistent */
        if ((rr->length != ccs_hdr_len) ||
        if ((SSL3_RECORD_get_length(rr) != ccs_hdr_len)
            (rr->off != 0) || (rr->data[0] != SSL3_MT_CCS)) {
                || (SSL3_RECORD_get_off(rr) != 0)
                || (SSL3_RECORD_get_data(rr)[0] != SSL3_MT_CCS)) {
            i = SSL_AD_ILLEGAL_PARAMETER;
            i = SSL_AD_ILLEGAL_PARAMETER;
            SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_BAD_CHANGE_CIPHER_SPEC);
            SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_BAD_CHANGE_CIPHER_SPEC);
            goto err;
            goto err;
        }
        }


        rr->length = 0;
        SSL3_RECORD_set_length(rr, 0);


        if (s->msg_callback)
        if (s->msg_callback)
            s->msg_callback(0, s->version, SSL3_RT_CHANGE_CIPHER_SPEC,
            s->msg_callback(0, s->version, SSL3_RT_CHANGE_CIPHER_SPEC,
                            rr->data, 1, s, s->msg_callback_arg);
                SSL3_RECORD_get_data(rr), 1, s, s->msg_callback_arg);


        /*
        /*
         * We can't process a CCS now, because previous handshake messages
         * We can't process a CCS now, because previous handshake messages
@@ -936,8 +940,8 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)


        /* this may just be a stale retransmit */
        /* this may just be a stale retransmit */
        dtls1_get_message_header(rr->data, &msg_hdr);
        dtls1_get_message_header(rr->data, &msg_hdr);
        if (rr->epoch != s->rlayer.d->r_epoch) {
        if (SSL3_RECORD_get_epoch(rr) != s->rlayer.d->r_epoch) {
            rr->length = 0;
            SSL3_RECORD_set_length(rr, 0);
            goto start;
            goto start;
        }
        }


@@ -950,7 +954,7 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
                return -1;
                return -1;


            dtls1_retransmit_buffered_messages(s);
            dtls1_retransmit_buffered_messages(s);
            rr->length = 0;
            SSL3_RECORD_set_length(rr, 0);
            goto start;
            goto start;
        }
        }


@@ -988,11 +992,11 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
        goto start;
        goto start;
    }
    }


    switch (rr->type) {
    switch (SSL3_RECORD_get_type(rr)) {
    default:
    default:
        /* TLS just ignores unknown message types */
        /* TLS just ignores unknown message types */
        if (s->version == TLS1_VERSION) {
        if (s->version == TLS1_VERSION) {
            rr->length = 0;
            SSL3_RECORD_set_length(rr, 0);
            goto start;
            goto start;
        }
        }
        al = SSL_AD_UNEXPECTED_MESSAGE;
        al = SSL_AD_UNEXPECTED_MESSAGE;
@@ -1139,12 +1143,12 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf,
            goto err;
            goto err;
    }
    }


    p = wb->buf + prefix_len;
    p = SSL3_BUFFER_get_buf(wb) + prefix_len;


    /* write the header */
    /* write the header */


    *(p++) = type & 0xff;
    *(p++) = type & 0xff;
    wr->type = type;
    SSL3_RECORD_set_type(wr, type);
    /*
    /*
     * Special case: for hello verify request, client version 1.0 and we
     * 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
     * haven't decided which version to use yet send back using version 1.0
@@ -1179,9 +1183,9 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf,
        eivlen = 0;
        eivlen = 0;


    /* lets setup the record stuff. */
    /* lets setup the record stuff. */
    wr->data = p + eivlen;      /* make room for IV in case of CBC */
    SSL3_RECORD_set_data(wr, p + eivlen); /* make room for IV in case of CBC */
    wr->length = (int)len;
    SSL3_RECORD_set_length(wr, (int)len);
    wr->input = (unsigned char *)buf;
    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
@@ -1194,8 +1198,9 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf,
            goto err;
            goto err;
        }
        }
    } else {
    } else {
        memcpy(wr->data, wr->input, wr->length);
        memcpy(SSL3_RECORD_get_data(wr), SSL3_RECORD_get_input(wr),
        wr->input = wr->data;
               SSL3_RECORD_get_length(wr));
        SSL3_RECORD_reset_input(wr);
    }
    }


    /*
    /*
@@ -1205,17 +1210,18 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf,
     */
     */


    if (mac_size != 0) {
    if (mac_size != 0) {
        if (s->method->ssl3_enc->mac(s, &(p[wr->length + eivlen]), 1) < 0)
        if (s->method->ssl3_enc->mac(s,
                &(p[SSL3_RECORD_get_length(wr) + eivlen]), 1) < 0)
            goto err;
            goto err;
        wr->length += mac_size;
        SSL3_RECORD_add_length(wr, mac_size);
    }
    }


    /* this is true regardless of mac size */
    /* this is true regardless of mac size */
    wr->input = p;
    SSL3_RECORD_set_data(wr, p);
    wr->data = p;
    SSL3_RECORD_reset_input(wr);


    if (eivlen)
    if (eivlen)
        wr->length += eivlen;
        SSL3_RECORD_add_length(wr, eivlen);


    if (s->method->ssl3_enc->enc(s, 1) < 1)
    if (s->method->ssl3_enc->enc(s, 1) < 1)
        goto err;
        goto err;
@@ -1237,7 +1243,7 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf,


    memcpy(pseq, &(s->rlayer.write_sequence[2]), 6);
    memcpy(pseq, &(s->rlayer.write_sequence[2]), 6);
    pseq += 6;
    pseq += 6;
    s2n(wr->length, pseq);
    s2n(SSL3_RECORD_get_length(wr), pseq);


    if (s->msg_callback)
    if (s->msg_callback)
        s->msg_callback(1, 0, SSL3_RT_HEADER, pseq - DTLS1_RT_HEADER_LENGTH,
        s->msg_callback(1, 0, SSL3_RT_HEADER, pseq - DTLS1_RT_HEADER_LENGTH,
@@ -1247,8 +1253,8 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf,
     * 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
     * wr->length long
     */
     */
    wr->type = type;            /* not needed but helps for debugging */
    SSL3_RECORD_set_type(wr, type); /* not needed but helps for debugging */
    wr->length += DTLS1_RT_HEADER_LENGTH;
    SSL3_RECORD_add_length(wr, DTLS1_RT_HEADER_LENGTH);


    ssl3_record_sequence_update(&(s->rlayer.write_sequence[0]));
    ssl3_record_sequence_update(&(s->rlayer.write_sequence[0]));


@@ -1261,8 +1267,8 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf,
    }
    }


    /* now let's set up wb */
    /* now let's set up wb */
    wb->left = prefix_len + wr->length;
    SSL3_BUFFER_set_left(wb, prefix_len + SSL3_RECORD_get_length(wr));
    wb->offset = 0;
    SSL3_BUFFER_set_offset(wb, 0);


    /*
    /*
     * memorize arguments so that ssl3_write_pending can detect bad write
     * memorize arguments so that ssl3_write_pending can detect bad write
+69 −62
Original line number Original line Diff line number Diff line
@@ -683,7 +683,7 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
     * first check if there is a SSL3_BUFFER still being written out.  This
     * first check if there is a SSL3_BUFFER still being written out.  This
     * will happen with non blocking IO
     * will happen with non blocking IO
     */
     */
    if (wb->left != 0)
    if (SSL3_BUFFER_get_left(wb) != 0)
        return (ssl3_write_pending(s, type, buf, len));
        return (ssl3_write_pending(s, type, buf, len));


    /* If we have an alert to send, lets send it */
    /* If we have an alert to send, lets send it */
@@ -694,7 +694,7 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
        /* if it went, fall through and send more stuff */
        /* if it went, fall through and send more stuff */
    }
    }


    if (wb->buf == NULL)
    if (!SSL3_BUFFER_is_initialised(wb))
        if (!ssl3_setup_write_buffer(s))
        if (!ssl3_setup_write_buffer(s))
            return -1;
            return -1;


@@ -754,26 +754,26 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
         * multiple of SSL3_ALIGN_PAYLOAD, so if we want to align the real
         * multiple of SSL3_ALIGN_PAYLOAD, so if we want to align the real
         * payload, then we can just pretent we simply have two headers.
         * payload, then we can just pretent we simply have two headers.
         */
         */
        align = (long)wb->buf + 2 * SSL3_RT_HEADER_LENGTH;
        align = (long)SSL3_BUFFER_get_buf(wb) + 2 * SSL3_RT_HEADER_LENGTH;
        align = (-align) & (SSL3_ALIGN_PAYLOAD - 1);
        align = (-align) & (SSL3_ALIGN_PAYLOAD - 1);
#endif
#endif
        p = wb->buf + align;
        p = SSL3_BUFFER_get_buf(wb) + align;
        wb->offset = align;
        SSL3_BUFFER_set_offset(wb, align);
    } else if (prefix_len) {
    } else if (prefix_len) {
        p = wb->buf + wb->offset + prefix_len;
        p = SSL3_BUFFER_get_buf(wb) + SSL3_BUFFER_get_offset(wb) + prefix_len;
    } else {
    } else {
#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0
#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0
        align = (long)wb->buf + SSL3_RT_HEADER_LENGTH;
        align = (long)SSL3_BUFFER_get_buf(wb) + SSL3_RT_HEADER_LENGTH;
        align = (-align) & (SSL3_ALIGN_PAYLOAD - 1);
        align = (-align) & (SSL3_ALIGN_PAYLOAD - 1);
#endif
#endif
        p = wb->buf + align;
        p = SSL3_BUFFER_get_buf(wb) + align;
        wb->offset = align;
        SSL3_BUFFER_set_offset(wb, align);
    }
    }


    /* write the header */
    /* write the header */


    *(p++) = type & 0xff;
    *(p++) = type & 0xff;
    wr->type = type;
    SSL3_RECORD_set_type(wr, type);


    *(p++) = (s->version >> 8);
    *(p++) = (s->version >> 8);
    /*
    /*
@@ -806,9 +806,10 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
        eivlen = 0;
        eivlen = 0;


    /* lets setup the record stuff. */
    /* lets setup the record stuff. */
    wr->data = p + eivlen;
    SSL3_RECORD_set_data(wr, p + eivlen);
    wr->length = (int)len;
    SSL3_RECORD_set_length(wr, (int)len);
    wr->input = (unsigned char *)buf;
    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
@@ -822,7 +823,7 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
        }
        }
    } else {
    } else {
        memcpy(wr->data, wr->input, wr->length);
        memcpy(wr->data, wr->input, wr->length);
        wr->input = wr->data;
        SSL3_RECORD_reset_input(wr);
    }
    }


    /*
    /*
@@ -834,17 +835,17 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
    if (!SSL_USE_ETM(s) && mac_size != 0) {
    if (!SSL_USE_ETM(s) && mac_size != 0) {
        if (s->method->ssl3_enc->mac(s, &(p[wr->length + eivlen]), 1) < 0)
        if (s->method->ssl3_enc->mac(s, &(p[wr->length + eivlen]), 1) < 0)
            goto err;
            goto err;
        wr->length += mac_size;
        SSL3_RECORD_add_length(wr, mac_size);
    }
    }


    wr->input = p;
    SSL3_RECORD_set_data(wr, p);
    wr->data = p;
    SSL3_RECORD_reset_input(wr);


    if (eivlen) {
    if (eivlen) {
        /*
        /*
         * if (RAND_pseudo_bytes(p, eivlen) <= 0) goto err;
         * if (RAND_pseudo_bytes(p, eivlen) <= 0) goto err;
         */
         */
        wr->length += eivlen;
        SSL3_RECORD_add_length(wr, eivlen);
    }
    }


    if (s->method->ssl3_enc->enc(s, 1) < 1)
    if (s->method->ssl3_enc->enc(s, 1) < 1)
@@ -853,11 +854,11 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
    if (SSL_USE_ETM(s) && mac_size != 0) {
    if (SSL_USE_ETM(s) && mac_size != 0) {
        if (s->method->ssl3_enc->mac(s, p + wr->length, 1) < 0)
        if (s->method->ssl3_enc->mac(s, p + wr->length, 1) < 0)
            goto err;
            goto err;
        wr->length += mac_size;
        SSL3_RECORD_add_length(wr, mac_size);
    }
    }


    /* record length after mac and block padding */
    /* record length after mac and block padding */
    s2n(wr->length, plen);
    s2n(SSL3_RECORD_get_length(wr), plen);


    if (s->msg_callback)
    if (s->msg_callback)
        s->msg_callback(1, 0, SSL3_RT_HEADER, plen - 5, 5, s,
        s->msg_callback(1, 0, SSL3_RT_HEADER, plen - 5, 5, s,
@@ -867,19 +868,19 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
     * 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
     * wr->length long
     */
     */
    wr->type = type;            /* not needed but helps for debugging */
    SSL3_RECORD_set_type(wr, type);  /* not needed but helps for debugging */
    wr->length += SSL3_RT_HEADER_LENGTH;
    SSL3_RECORD_add_length(wr, SSL3_RT_HEADER_LENGTH);


    if (create_empty_fragment) {
    if (create_empty_fragment) {
        /*
        /*
         * we are in a recursive call; just return the length, don't write
         * we are in a recursive call; just return the length, don't write
         * out anything here
         * out anything here
         */
         */
        return wr->length;
        return SSL3_RECORD_get_length(wr);
    }
    }


    /* now let's set up wb */
    /* now let's set up wb */
    wb->left = prefix_len + wr->length;
    SSL3_BUFFER_set_left(wb, prefix_len + SSL3_RECORD_get_length(wr));


    /*
    /*
     * memorize arguments so that ssl3_write_pending can detect bad write
     * memorize arguments so that ssl3_write_pending can detect bad write
@@ -917,15 +918,15 @@ int ssl3_write_pending(SSL *s, int type, const unsigned char *buf,
        if (s->wbio != NULL) {
        if (s->wbio != NULL) {
            s->rwstate = SSL_WRITING;
            s->rwstate = SSL_WRITING;
            i = BIO_write(s->wbio,
            i = BIO_write(s->wbio,
                          (char *)&(wb->buf[wb->offset]),
                (char *)&(SSL3_BUFFER_get_buf(wb)[SSL3_BUFFER_get_offset(wb)]),
                          (unsigned int)wb->left);
                (unsigned int)SSL3_BUFFER_get_left(wb));
        } else {
        } else {
            SSLerr(SSL_F_SSL3_WRITE_PENDING, SSL_R_BIO_NOT_SET);
            SSLerr(SSL_F_SSL3_WRITE_PENDING, SSL_R_BIO_NOT_SET);
            i = -1;
            i = -1;
        }
        }
        if (i == wb->left) {
        if (i == SSL3_BUFFER_get_left(wb)) {
            wb->left = 0;
            SSL3_BUFFER_set_left(wb, 0);
            wb->offset += i;
            SSL3_BUFFER_add_offset(wb, i);
            s->rwstate = SSL_NOTHING;
            s->rwstate = SSL_NOTHING;
            return (s->rlayer.wpend_ret);
            return (s->rlayer.wpend_ret);
        } else if (i <= 0) {
        } else if (i <= 0) {
@@ -934,12 +935,12 @@ int ssl3_write_pending(SSL *s, int type, const unsigned char *buf,
                 * For DTLS, just drop it. That's kind of the whole point in
                 * For DTLS, just drop it. That's kind of the whole point in
                 * using a datagram service
                 * using a datagram service
                 */
                 */
                wb->left = 0;
                SSL3_BUFFER_set_left(wb, 0);
            }
            }
            return (i);
            return (i);
        }
        }
        wb->offset += i;
        SSL3_BUFFER_add_offset(wb, i);
        wb->left -= i;
        SSL3_BUFFER_add_left(wb, -i);
    }
    }
}
}


@@ -1039,7 +1040,8 @@ int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
    rr = &s->rlayer.rrec;
    rr = &s->rlayer.rrec;


    /* get new packet if necessary */
    /* get new packet if necessary */
    if ((rr->length == 0) || (s->rlayer.rstate == SSL_ST_READ_BODY)) {
    if ((SSL3_RECORD_get_length(rr) == 0)
            || (s->rlayer.rstate == SSL_ST_READ_BODY)) {
        ret = ssl3_get_record(s);
        ret = ssl3_get_record(s);
        if (ret <= 0)
        if (ret <= 0)
            return (ret);
            return (ret);
@@ -1049,7 +1051,7 @@ int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)


    if (s->s3->change_cipher_spec /* set when we receive ChangeCipherSpec,
    if (s->s3->change_cipher_spec /* set when we receive ChangeCipherSpec,
                                   * reset by ssl3_get_finished */
                                   * reset by ssl3_get_finished */
        && (rr->type != SSL3_RT_HANDSHAKE)) {
        && (SSL3_RECORD_get_type(rr) != SSL3_RT_HANDSHAKE)) {
        al = SSL_AD_UNEXPECTED_MESSAGE;
        al = SSL_AD_UNEXPECTED_MESSAGE;
        SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_DATA_BETWEEN_CCS_AND_FINISHED);
        SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_DATA_BETWEEN_CCS_AND_FINISHED);
        goto f_err;
        goto f_err;
@@ -1060,12 +1062,13 @@ int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
     * 'peek' mode)
     * 'peek' mode)
     */
     */
    if (s->shutdown & SSL_RECEIVED_SHUTDOWN) {
    if (s->shutdown & SSL_RECEIVED_SHUTDOWN) {
        rr->length = 0;
        SSL3_RECORD_set_length(rr, 0);
        s->rwstate = SSL_NOTHING;
        s->rwstate = SSL_NOTHING;
        return (0);
        return (0);
    }
    }


    if (type == rr->type) {     /* SSL3_RT_APPLICATION_DATA or
    if (type == SSL3_RECORD_get_type(rr)) {
        /* SSL3_RT_APPLICATION_DATA or
         * SSL3_RT_HANDSHAKE */
         * SSL3_RT_HANDSHAKE */
        /*
        /*
         * make sure that we are not getting application data when we are
         * make sure that we are not getting application data when we are
@@ -1081,18 +1084,18 @@ int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
        if (len <= 0)
        if (len <= 0)
            return (len);
            return (len);


        if ((unsigned int)len > rr->length)
        if ((unsigned int)len > SSL3_RECORD_get_length(rr))
            n = rr->length;
            n = SSL3_RECORD_get_length(rr);
        else
        else
            n = (unsigned int)len;
            n = (unsigned int)len;


        memcpy(buf, &(rr->data[rr->off]), n);
        memcpy(buf, &(rr->data[rr->off]), n);
        if (!peek) {
        if (!peek) {
            rr->length -= n;
            SSL3_RECORD_add_length(rr, -n);
            rr->off += n;
            SSL3_RECORD_add_off(rr, n);
            if (rr->length == 0) {
            if (SSL3_RECORD_get_length(rr) == 0) {
                s->rlayer.rstate = SSL_ST_READ_HEADER;
                s->rlayer.rstate = SSL_ST_READ_HEADER;
                rr->off = 0;
                SSL3_RECORD_set_off(rr, 0);
                if (s->mode & SSL_MODE_RELEASE_BUFFERS
                if (s->mode & SSL_MODE_RELEASE_BUFFERS
                    && SSL3_BUFFER_get_left(&s->rlayer.rbuf) == 0)
                    && SSL3_BUFFER_get_left(&s->rlayer.rbuf) == 0)
                    ssl3_release_read_buffer(s);
                    ssl3_release_read_buffer(s);
@@ -1115,25 +1118,25 @@ int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
        unsigned char *dest = NULL;
        unsigned char *dest = NULL;
        unsigned int *dest_len = NULL;
        unsigned int *dest_len = NULL;


        if (rr->type == SSL3_RT_HANDSHAKE) {
        if (SSL3_RECORD_get_type(rr) == SSL3_RT_HANDSHAKE) {
            dest_maxlen = sizeof s->rlayer.handshake_fragment;
            dest_maxlen = sizeof s->rlayer.handshake_fragment;
            dest = s->rlayer.handshake_fragment;
            dest = s->rlayer.handshake_fragment;
            dest_len = &s->rlayer.handshake_fragment_len;
            dest_len = &s->rlayer.handshake_fragment_len;
        } else if (rr->type == SSL3_RT_ALERT) {
        } else if (SSL3_RECORD_get_type(rr) == SSL3_RT_ALERT) {
            dest_maxlen = sizeof s->rlayer.alert_fragment;
            dest_maxlen = sizeof s->rlayer.alert_fragment;
            dest = s->rlayer.alert_fragment;
            dest = s->rlayer.alert_fragment;
            dest_len = &s->rlayer.alert_fragment_len;
            dest_len = &s->rlayer.alert_fragment_len;
        }
        }
#ifndef OPENSSL_NO_HEARTBEATS
#ifndef OPENSSL_NO_HEARTBEATS
        else if (rr->type == TLS1_RT_HEARTBEAT) {
        else if (SSL3_RECORD_get_type(rr)== TLS1_RT_HEARTBEAT) {
            /* We can ignore 0 return values */
            /* We can ignore 0 return values */
            if(tls1_process_heartbeat(s, SSL3_RECORD_get_data(&s->rlayer.rrec),
            if(tls1_process_heartbeat(s, SSL3_RECORD_get_data(rr),
                    SSL3_RECORD_get_length(&s->rlayer.rrec)) < 0) {
                    SSL3_RECORD_get_length(rr)) < 0) {
                return -1;
                return -1;
            }
            }


            /* Exit and notify application to read again */
            /* Exit and notify application to read again */
            rr->length = 0;
            SSL3_RECORD_set_length(rr, 0);
            s->rwstate = SSL_READING;
            s->rwstate = SSL_READING;
            BIO_clear_retry_flags(SSL_get_rbio(s));
            BIO_clear_retry_flags(SSL_get_rbio(s));
            BIO_set_retry_read(SSL_get_rbio(s));
            BIO_set_retry_read(SSL_get_rbio(s));
@@ -1143,13 +1146,15 @@ int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)


        if (dest_maxlen > 0) {
        if (dest_maxlen > 0) {
            n = dest_maxlen - *dest_len; /* available space in 'dest' */
            n = dest_maxlen - *dest_len; /* available space in 'dest' */
            if (rr->length < n)
            if (SSL3_RECORD_get_length(rr) < n)
                n = rr->length; /* available bytes */
                n = SSL3_RECORD_get_length(rr); /* available bytes */


            /* now move 'n' bytes: */
            /* now move 'n' bytes: */
            while (n-- > 0) {
            while (n-- > 0) {
                dest[(*dest_len)++] = rr->data[rr->off++];
                dest[(*dest_len)++] =
                rr->length--;
                    SSL3_RECORD_get_data(rr)[SSL3_RECORD_get_off(rr)];
                SSL3_RECORD_add_off(rr, 1);
                SSL3_RECORD_add_length(rr, -1);
            }
            }


            if (*dest_len < dest_maxlen)
            if (*dest_len < dest_maxlen)
@@ -1235,7 +1240,7 @@ int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
        (s->rlayer.handshake_fragment[0] == SSL3_MT_CLIENT_HELLO) &&
        (s->rlayer.handshake_fragment[0] == SSL3_MT_CLIENT_HELLO) &&
        (s->session != NULL) && (s->session->cipher != NULL) &&
        (s->session != NULL) && (s->session->cipher != NULL) &&
        !(s->ctx->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) {
        !(s->ctx->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) {
        rr->length = 0;
        SSL3_RECORD_set_length(rr, 0);
        ssl3_send_alert(s, SSL3_AL_WARNING, SSL_AD_NO_RENEGOTIATION);
        ssl3_send_alert(s, SSL3_AL_WARNING, SSL_AD_NO_RENEGOTIATION);
        goto start;
        goto start;
    }
    }
@@ -1306,17 +1311,18 @@ int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
    if (s->shutdown & SSL_SENT_SHUTDOWN) { /* but we have not received a
    if (s->shutdown & SSL_SENT_SHUTDOWN) { /* but we have not received a
                                            * shutdown */
                                            * shutdown */
        s->rwstate = SSL_NOTHING;
        s->rwstate = SSL_NOTHING;
        rr->length = 0;
        SSL3_RECORD_set_length(rr, 0);
        return (0);
        return (0);
    }
    }


    if (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC) {
    if (SSL3_RECORD_get_type(rr) == SSL3_RT_CHANGE_CIPHER_SPEC) {
        /*
        /*
         * 'Change Cipher Spec' is just a single byte, so we know exactly
         * 'Change Cipher Spec' is just a single byte, so we know exactly
         * what the record payload has to look like
         * what the record payload has to look like
         */
         */
        if ((rr->length != 1) || (rr->off != 0) ||
        if ((SSL3_RECORD_get_length(rr) != 1)
            (rr->data[0] != SSL3_MT_CCS)) {
            || (SSL3_RECORD_get_off(rr) != 0)
            || (SSL3_RECORD_get_data(rr)[0] != SSL3_MT_CCS)) {
            al = SSL_AD_ILLEGAL_PARAMETER;
            al = SSL_AD_ILLEGAL_PARAMETER;
            SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_BAD_CHANGE_CIPHER_SPEC);
            SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_BAD_CHANGE_CIPHER_SPEC);
            goto f_err;
            goto f_err;
@@ -1337,11 +1343,12 @@ int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)


        s->s3->flags &= ~SSL3_FLAGS_CCS_OK;
        s->s3->flags &= ~SSL3_FLAGS_CCS_OK;


        rr->length = 0;
        SSL3_RECORD_set_length(rr, 0);


        if (s->msg_callback)
        if (s->msg_callback)
            s->msg_callback(0, s->version, SSL3_RT_CHANGE_CIPHER_SPEC,
            s->msg_callback(0, s->version, SSL3_RT_CHANGE_CIPHER_SPEC,
                            rr->data, 1, s, s->msg_callback_arg);
                            SSL3_RECORD_get_data(rr), 1, s,
                            s->msg_callback_arg);


        s->s3->change_cipher_spec = 1;
        s->s3->change_cipher_spec = 1;
        if (!ssl3_do_change_cipher_spec(s))
        if (!ssl3_do_change_cipher_spec(s))
@@ -1388,14 +1395,14 @@ int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
        goto start;
        goto start;
    }
    }


    switch (rr->type) {
    switch (SSL3_RECORD_get_type(rr)) {
    default:
    default:
        /*
        /*
         * TLS up to v1.1 just ignores unknown message types: TLS v1.2 give
         * TLS up to v1.1 just ignores unknown message types: TLS v1.2 give
         * an unexpected message alert.
         * an unexpected message alert.
         */
         */
        if (s->version >= TLS1_VERSION && s->version <= TLS1_1_VERSION) {
        if (s->version >= TLS1_VERSION && s->version <= TLS1_1_VERSION) {
            rr->length = 0;
            SSL3_RECORD_set_length(rr, 0);
            goto start;
            goto start;
        }
        }
        al = SSL_AD_UNEXPECTED_MESSAGE;
        al = SSL_AD_UNEXPECTED_MESSAGE;
+16 −0
Original line number Original line Diff line number Diff line
@@ -155,6 +155,11 @@ void dtls1_record_bitmap_update(SSL *s, DTLS1_BITMAP *bitmap);
#define SSL3_BUFFER_get_len(b)              ((b)->len)
#define SSL3_BUFFER_get_len(b)              ((b)->len)
#define SSL3_BUFFER_set_len(b, l)           ((b)->len = (l))
#define SSL3_BUFFER_set_len(b, l)           ((b)->len = (l))
#define SSL3_BUFFER_get_left(b)             ((b)->left)
#define SSL3_BUFFER_get_left(b)             ((b)->left)
#define SSL3_BUFFER_set_left(b, l)          ((b)->left = (l))
#define SSL3_BUFFER_add_left(b, l)          ((b)->left += (l))
#define SSL3_BUFFER_get_offset(b)           ((b)->offset)
#define SSL3_BUFFER_set_offset(b, o)        ((b)->offset = (o))
#define SSL3_BUFFER_add_offset(b, o)        ((b)->offset += (o))
#define SSL3_BUFFER_is_initialised(b)       ((b)->buf != NULL)
#define SSL3_BUFFER_is_initialised(b)       ((b)->buf != NULL)


void SSL3_BUFFER_set_data(SSL3_BUFFER *b, const unsigned char *d, int n);
void SSL3_BUFFER_set_data(SSL3_BUFFER *b, const unsigned char *d, int n);
@@ -167,9 +172,20 @@ int ssl3_release_write_buffer(SSL *s);
/* Macros/functions provided by the SSL3_RECORD component */
/* Macros/functions provided by the SSL3_RECORD component */


#define SSL3_RECORD_get_type(r)                 ((r)->type)
#define SSL3_RECORD_get_type(r)                 ((r)->type)
#define SSL3_RECORD_set_type(r, t)              ((r)->type = (t))
#define SSL3_RECORD_get_length(r)               ((r)->length)
#define SSL3_RECORD_get_length(r)               ((r)->length)
#define SSL3_RECORD_set_length(r, l)            ((r)->length = (l))
#define SSL3_RECORD_add_length(r, l)            ((r)->length += (l))
#define SSL3_RECORD_get_data(r)                 ((r)->data)
#define SSL3_RECORD_get_data(r)                 ((r)->data)
#define SSL3_RECORD_set_data(r, d)              ((r)->data = (d))
#define SSL3_RECORD_get_input(r)                ((r)->input)
#define SSL3_RECORD_set_input(r, i)             ((r)->input = (i))
#define SSL3_RECORD_reset_input(r)              ((r)->input = (r)->data)
#define SSL3_RECORD_get_seq_num(r)              ((r)->seq_num)
#define SSL3_RECORD_get_seq_num(r)              ((r)->seq_num)
#define SSL3_RECORD_get_off(r)                  ((r)->off)
#define SSL3_RECORD_set_off(r, o)               ((r)->off = (o))
#define SSL3_RECORD_add_off(r, o)               ((r)->off += (o))
#define SSL3_RECORD_get_epoch(r)                ((r)->epoch)


void SSL3_RECORD_clear(SSL3_RECORD *r);
void SSL3_RECORD_clear(SSL3_RECORD *r);
void SSL3_RECORD_release(SSL3_RECORD *r);
void SSL3_RECORD_release(SSL3_RECORD *r);