statem_dtls.c 38.7 KB
Newer Older
1
/*
R
Rich Salz 已提交
2
 * Copyright 2005-2016 The OpenSSL Project Authors. All Rights Reserved.
3
 *
R
Rich Salz 已提交
4 5 6 7
 * 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
B
Ben Laurie 已提交
8 9 10 11 12
 */

#include <limits.h>
#include <string.h>
#include <stdio.h>
M
Matt Caswell 已提交
13
#include "../ssl_locl.h"
M
Matt Caswell 已提交
14
#include "statem_locl.h"
B
Ben Laurie 已提交
15 16 17 18 19
#include <openssl/buffer.h>
#include <openssl/objects.h>
#include <openssl/evp.h>
#include <openssl/x509.h>

D
Dr. Stephen Henson 已提交
20 21 22
#define RSMBLY_BITMASK_SIZE(msg_len) (((msg_len) + 7) / 8)

#define RSMBLY_BITMASK_MARK(bitmask, start, end) { \
23 24 25 26 27 28 29 30 31
                        if ((end) - (start) <= 8) { \
                                long ii; \
                                for (ii = (start); ii < (end); ii++) bitmask[((ii) >> 3)] |= (1 << ((ii) & 7)); \
                        } else { \
                                long ii; \
                                bitmask[((start) >> 3)] |= bitmask_start_values[((start) & 7)]; \
                                for (ii = (((start) >> 3) + 1); ii < ((((end) - 1)) >> 3); ii++) bitmask[ii] = 0xff; \
                                bitmask[(((end) - 1) >> 3)] |= bitmask_end_values[((end) & 7)]; \
                        } }
D
Dr. Stephen Henson 已提交
32 33

#define RSMBLY_BITMASK_IS_COMPLETE(bitmask, msg_len, is_complete) { \
34 35 36 37 38 39
                        long ii; \
                        OPENSSL_assert((msg_len) > 0); \
                        is_complete = 1; \
                        if (bitmask[(((msg_len) - 1) >> 3)] != bitmask_end_values[((msg_len) & 7)]) is_complete = 0; \
                        if (is_complete) for (ii = (((msg_len) - 1) >> 3) - 1; ii >= 0 ; ii--) \
                                if (bitmask[ii] != 0xff) { is_complete = 0; break; } }
D
Dr. Stephen Henson 已提交
40

41 42 43 44
static unsigned char bitmask_start_values[] =
    { 0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80 };
static unsigned char bitmask_end_values[] =
    { 0xff, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f };
B
Ben Laurie 已提交
45

46 47 48
static void dtls1_fix_message_header(SSL *s, unsigned long frag_off,
                                     unsigned long frag_len);
static unsigned char *dtls1_write_message_header(SSL *s, unsigned char *p);
B
Ben Laurie 已提交
49
static void dtls1_set_message_header_int(SSL *s, unsigned char mt,
50 51 52 53
                                         unsigned long len,
                                         unsigned short seq_num,
                                         unsigned long frag_off,
                                         unsigned long frag_len);
54
static int dtls_get_reassembled_message(SSL *s, long *len);
55 56 57 58 59 60 61 62

static hm_fragment *dtls1_hm_fragment_new(unsigned long frag_len,
                                          int reassembly)
{
    hm_fragment *frag = NULL;
    unsigned char *buf = NULL;
    unsigned char *bitmask = NULL;

R
Rich Salz 已提交
63
    frag = OPENSSL_malloc(sizeof(*frag));
64 65 66 67
    if (frag == NULL)
        return NULL;

    if (frag_len) {
R
Rich Salz 已提交
68
        buf = OPENSSL_malloc(frag_len);
69 70 71 72 73 74 75 76 77 78 79
        if (buf == NULL) {
            OPENSSL_free(frag);
            return NULL;
        }
    }

    /* zero length fragment gets zero frag->fragment */
    frag->fragment = buf;

    /* Initialize reassembly bitmask if necessary */
    if (reassembly) {
R
Rich Salz 已提交
80
        bitmask = OPENSSL_zalloc(RSMBLY_BITMASK_SIZE(frag_len));
81
        if (bitmask == NULL) {
R
Rich Salz 已提交
82
            OPENSSL_free(buf);
83 84 85 86 87 88 89 90 91
            OPENSSL_free(frag);
            return NULL;
        }
    }

    frag->reassembly = bitmask;

    return frag;
}
B
Ben Laurie 已提交
92

93
void dtls1_hm_fragment_free(hm_fragment *frag)
94
{
R
Rich Salz 已提交
95 96
    if (!frag)
        return;
97 98 99
    if (frag->msg_header.is_ccs) {
        EVP_CIPHER_CTX_free(frag->msg_header.
                            saved_retransmit_state.enc_write_ctx);
100
        EVP_MD_CTX_free(frag->msg_header.saved_retransmit_state.write_hash);
101
    }
R
Rich Salz 已提交
102 103
    OPENSSL_free(frag->fragment);
    OPENSSL_free(frag->reassembly);
104 105
    OPENSSL_free(frag);
}
B
Ben Laurie 已提交
106

107 108 109 110
/*
 * send s->init_buf in records of type 'type' (SSL3_RT_HANDSHAKE or
 * SSL3_RT_CHANGE_CIPHER_SPEC)
 */
111
int dtls1_do_write(SSL *s, int type)
112 113 114 115 116 117 118 119 120
{
    int ret;
    unsigned int curr_mtu;
    int retry = 1;
    unsigned int len, frag_off, mac_size, blocksize, used_len;

    if (!dtls1_query_mtu(s))
        return -1;

121 122 123
    if (s->d1->mtu < dtls1_min_mtu(s))
        /* should have something reasonable now */
        return -1;
124 125 126

    if (s->init_off == 0 && type == SSL3_RT_HANDSHAKE)
        OPENSSL_assert(s->init_num ==
E
Emilia Kasper 已提交
127
                       (int)s->d1->w_msg_hdr.msg_len + DTLS1_HM_HEADER_LENGTH);
128 129 130

    if (s->write_hash) {
        if (s->enc_write_ctx
131
            && (EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(s->enc_write_ctx)) &
T
tjmao 已提交
132
                EVP_CIPH_FLAG_AEAD_CIPHER) != 0)
133 134 135 136 137 138 139 140
            mac_size = 0;
        else
            mac_size = EVP_MD_CTX_size(s->write_hash);
    } else
        mac_size = 0;

    if (s->enc_write_ctx &&
        (EVP_CIPHER_CTX_mode(s->enc_write_ctx) == EVP_CIPH_CBC_MODE))
141
        blocksize = 2 * EVP_CIPHER_CTX_block_size(s->enc_write_ctx);
142 143 144 145
    else
        blocksize = 0;

    frag_off = 0;
146 147
    s->rwstate = SSL_NOTHING;

148 149
    /* s->init_num shouldn't ever be < 0...but just in case */
    while (s->init_num > 0) {
M
Matt Caswell 已提交
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183
        if (type == SSL3_RT_HANDSHAKE && s->init_off != 0) {
            /* We must be writing a fragment other than the first one */

            if (frag_off > 0) {
                /* This is the first attempt at writing out this fragment */

                if (s->init_off <= DTLS1_HM_HEADER_LENGTH) {
                    /*
                     * Each fragment that was already sent must at least have
                     * contained the message header plus one other byte.
                     * Therefore |init_off| must have progressed by at least
                     * |DTLS1_HM_HEADER_LENGTH + 1| bytes. If not something went
                     * wrong.
                     */
                    return -1;
                }

                /*
                 * Adjust |init_off| and |init_num| to allow room for a new
                 * message header for this fragment.
                 */
                s->init_off -= DTLS1_HM_HEADER_LENGTH;
                s->init_num += DTLS1_HM_HEADER_LENGTH;
            } else {
                /*
                 * We must have been called again after a retry so use the
                 * fragment offset from our last attempt. We do not need
                 * to adjust |init_off| and |init_num| as above, because
                 * that should already have been done before the retry.
                 */
                frag_off = s->d1->w_msg_hdr.frag_off;
            }
        }

184
        used_len = BIO_wpending(s->wbio) + DTLS1_RT_HEADER_LENGTH
185 186 187 188 189 190 191 192 193 194
            + mac_size + blocksize;
        if (s->d1->mtu > used_len)
            curr_mtu = s->d1->mtu - used_len;
        else
            curr_mtu = 0;

        if (curr_mtu <= DTLS1_HM_HEADER_LENGTH) {
            /*
             * grr.. we could get an error if MTU picked was wrong
             */
195
            ret = BIO_flush(s->wbio);
196 197
            if (ret <= 0) {
                s->rwstate = SSL_WRITING;
198
                return ret;
199
            }
200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231
            used_len = DTLS1_RT_HEADER_LENGTH + mac_size + blocksize;
            if (s->d1->mtu > used_len + DTLS1_HM_HEADER_LENGTH) {
                curr_mtu = s->d1->mtu - used_len;
            } else {
                /* Shouldn't happen */
                return -1;
            }
        }

        /*
         * We just checked that s->init_num > 0 so this cast should be safe
         */
        if (((unsigned int)s->init_num) > curr_mtu)
            len = curr_mtu;
        else
            len = s->init_num;

        /* Shouldn't ever happen */
        if (len > INT_MAX)
            len = INT_MAX;

        /*
         * XDTLS: this function is too long.  split out the CCS part
         */
        if (type == SSL3_RT_HANDSHAKE) {
            if (len < DTLS1_HM_HEADER_LENGTH) {
                /*
                 * len is so small that we really can't do anything sensible
                 * so fail
                 */
                return -1;
            }
E
Emilia Kasper 已提交
232
            dtls1_fix_message_header(s, frag_off, len - DTLS1_HM_HEADER_LENGTH);
233 234 235 236 237 238

            dtls1_write_message_header(s,
                                       (unsigned char *)&s->init_buf->
                                       data[s->init_off]);
        }

E
Emilia Kasper 已提交
239
        ret = dtls1_write_bytes(s, type, &s->init_buf->data[s->init_off], len);
240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293
        if (ret < 0) {
            /*
             * might need to update MTU here, but we don't know which
             * previous packet caused the failure -- so can't really
             * retransmit anything.  continue as if everything is fine and
             * wait for an alert to handle the retransmit
             */
            if (retry && BIO_ctrl(SSL_get_wbio(s),
                                  BIO_CTRL_DGRAM_MTU_EXCEEDED, 0, NULL) > 0) {
                if (!(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)) {
                    if (!dtls1_query_mtu(s))
                        return -1;
                    /* Have one more go */
                    retry = 0;
                } else
                    return -1;
            } else {
                return (-1);
            }
        } else {

            /*
             * bad if this assert fails, only part of the handshake message
             * got sent.  but why would this happen?
             */
            OPENSSL_assert(len == (unsigned int)ret);

            if (type == SSL3_RT_HANDSHAKE && !s->d1->retransmitting) {
                /*
                 * should not be done for 'Hello Request's, but in that case
                 * we'll ignore the result anyway
                 */
                unsigned char *p =
                    (unsigned char *)&s->init_buf->data[s->init_off];
                const struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr;
                int xlen;

                if (frag_off == 0 && s->version != DTLS1_BAD_VER) {
                    /*
                     * reconstruct message header is if it is being sent in
                     * single fragment
                     */
                    *p++ = msg_hdr->type;
                    l2n3(msg_hdr->msg_len, p);
                    s2n(msg_hdr->seq, p);
                    l2n3(0, p);
                    l2n3(msg_hdr->msg_len, p);
                    p -= DTLS1_HM_HEADER_LENGTH;
                    xlen = ret;
                } else {
                    p += DTLS1_HM_HEADER_LENGTH;
                    xlen = ret - DTLS1_HM_HEADER_LENGTH;
                }

294 295
                if (!ssl3_finish_mac(s, p, xlen))
                    return -1;
296 297 298 299 300 301 302 303 304 305 306 307 308 309 310
            }

            if (ret == s->init_num) {
                if (s->msg_callback)
                    s->msg_callback(1, s->version, type, s->init_buf->data,
                                    (size_t)(s->init_off + s->init_num), s,
                                    s->msg_callback_arg);

                s->init_off = 0; /* done writing this message */
                s->init_num = 0;

                return (1);
            }
            s->init_off += ret;
            s->init_num -= ret;
M
Matt Caswell 已提交
311 312 313 314 315 316 317 318 319 320
            ret -= DTLS1_HM_HEADER_LENGTH;
            frag_off += ret;

            /*
             * We save the fragment offset for the next fragment so we have it
             * available in case of an IO retry. We don't know the length of the
             * next fragment yet so just set that to 0 for now. It will be
             * updated again later.
             */
            dtls1_fix_message_header(s, frag_off, 0);
321 322 323 324 325
        }
    }
    return (0);
}

326 327 328 329 330 331 332 333 334 335 336 337 338
int dtls_get_message(SSL *s, int *mt, unsigned long *len)
{
    struct hm_header_st *msg_hdr;
    unsigned char *p;
    unsigned long msg_len;
    int ok;
    long tmplen;

    msg_hdr = &s->d1->r_msg_hdr;
    memset(msg_hdr, 0, sizeof(*msg_hdr));

 again:
    ok = dtls_get_reassembled_message(s, &tmplen);
E
Emilia Kasper 已提交
339
    if (tmplen == DTLS1_HM_BAD_FRAGMENT || tmplen == DTLS1_HM_FRAGMENT_RETRY) {
340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357
        /* bad fragment received */
        goto again;
    } else if (tmplen <= 0 && !ok) {
        return 0;
    }

    *mt = s->s3->tmp.message_type;

    p = (unsigned char *)s->init_buf->data;

    if (*mt == SSL3_MT_CHANGE_CIPHER_SPEC) {
        if (s->msg_callback) {
            s->msg_callback(0, s->version, SSL3_RT_CHANGE_CIPHER_SPEC,
                            p, 1, s, s->msg_callback_arg);
        }
        /*
         * This isn't a real handshake message so skip the processing below.
         */
358
        *len = (unsigned long)tmplen;
359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374
        return 1;
    }

    msg_len = msg_hdr->msg_len;

    /* reconstruct message header */
    *(p++) = msg_hdr->type;
    l2n3(msg_len, p);
    s2n(msg_hdr->seq, p);
    l2n3(0, p);
    l2n3(msg_len, p);
    if (s->version != DTLS1_BAD_VER) {
        p -= DTLS1_HM_HEADER_LENGTH;
        msg_len += DTLS1_HM_HEADER_LENGTH;
    }

375 376
    if (!ssl3_finish_mac(s, p, msg_len))
        return 0;
377 378 379 380 381 382 383 384 385 386 387 388 389 390 391
    if (s->msg_callback)
        s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE,
                        p, msg_len, s, s->msg_callback_arg);

    memset(msg_hdr, 0, sizeof(*msg_hdr));

    s->d1->handshake_read_seq++;

    s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH;
    *len = s->init_num;

    return 1;
}

static int dtls1_preprocess_fragment(SSL *s, struct hm_header_st *msg_hdr)
392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409
{
    size_t frag_off, frag_len, msg_len;

    msg_len = msg_hdr->msg_len;
    frag_off = msg_hdr->frag_off;
    frag_len = msg_hdr->frag_len;

    /* sanity checking */
    if ((frag_off + frag_len) > msg_len) {
        SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT, SSL_R_EXCESSIVE_MESSAGE_SIZE);
        return SSL_AD_ILLEGAL_PARAMETER;
    }

    if (s->d1->r_msg_hdr.frag_off == 0) { /* first fragment */
        /*
         * msg_len is limited to 2^24, but is effectively checked against max
         * above
         */
E
Emilia Kasper 已提交
410
        if (!BUF_MEM_grow_clean(s->init_buf, msg_len + DTLS1_HM_HEADER_LENGTH)) {
411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430
            SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT, ERR_R_BUF_LIB);
            return SSL_AD_INTERNAL_ERROR;
        }

        s->s3->tmp.message_size = msg_len;
        s->d1->r_msg_hdr.msg_len = msg_len;
        s->s3->tmp.message_type = msg_hdr->type;
        s->d1->r_msg_hdr.type = msg_hdr->type;
        s->d1->r_msg_hdr.seq = msg_hdr->seq;
    } else if (msg_len != s->d1->r_msg_hdr.msg_len) {
        /*
         * They must be playing with us! BTW, failure to enforce upper limit
         * would open possibility for buffer overrun.
         */
        SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT, SSL_R_EXCESSIVE_MESSAGE_SIZE);
        return SSL_AD_ILLEGAL_PARAMETER;
    }

    return 0;                   /* no error */
}
A
Andy Polyakov 已提交
431

432
static int dtls1_retrieve_buffered_fragment(SSL *s, int *ok)
433
{
434 435 436 437 438 439
    /*-
     * (0) check whether the desired fragment is available
     * if so:
     * (1) copy over the fragment to s->init_buf->data[]
     * (2) update s->init_num
     */
440 441 442 443 444 445
    pitem *item;
    hm_fragment *frag;
    int al;

    *ok = 0;

446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461
    do {
        item = pqueue_peek(s->d1->buffered_messages);
        if (item == NULL)
            return 0;

        frag = (hm_fragment *)item->data;

        if (frag->msg_header.seq < s->d1->handshake_read_seq) {
            /* This is a stale message that has been buffered so clear it */
            pqueue_pop(s->d1->buffered_messages);
            dtls1_hm_fragment_free(frag);
            pitem_free(item);
            item = NULL;
            frag = NULL;
        }
    } while (item == NULL);
462 463 464 465 466 467 468 469 470

    /* Don't return if reassembly still in progress */
    if (frag->reassembly != NULL)
        return 0;

    if (s->d1->handshake_read_seq == frag->msg_header.seq) {
        unsigned long frag_len = frag->msg_header.frag_len;
        pqueue_pop(s->d1->buffered_messages);

471
        al = dtls1_preprocess_fragment(s, &frag->msg_header);
472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500

        if (al == 0) {          /* no alert */
            unsigned char *p =
                (unsigned char *)s->init_buf->data + DTLS1_HM_HEADER_LENGTH;
            memcpy(&p[frag->msg_header.frag_off], frag->fragment,
                   frag->msg_header.frag_len);
        }

        dtls1_hm_fragment_free(frag);
        pitem_free(item);

        if (al == 0) {
            *ok = 1;
            return frag_len;
        }

        ssl3_send_alert(s, SSL3_AL_FATAL, al);
        s->init_num = 0;
        *ok = 0;
        return -1;
    } else
        return 0;
}

/*
 * dtls1_max_handshake_message_len returns the maximum number of bytes
 * permitted in a DTLS handshake message for |s|. The minimum is 16KB, but
 * may be greater if the maximum certificate list size requires it.
 */
501
static unsigned long dtls1_max_handshake_message_len(const SSL *s)
502 503 504 505 506 507 508
{
    unsigned long max_len =
        DTLS1_HM_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH;
    if (max_len < (unsigned long)s->max_cert_list)
        return s->max_cert_list;
    return max_len;
}
B
Ben Laurie 已提交
509

D
Dr. Stephen Henson 已提交
510
static int
511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556
dtls1_reassemble_fragment(SSL *s, const struct hm_header_st *msg_hdr, int *ok)
{
    hm_fragment *frag = NULL;
    pitem *item = NULL;
    int i = -1, is_complete;
    unsigned char seq64be[8];
    unsigned long frag_len = msg_hdr->frag_len;

    if ((msg_hdr->frag_off + frag_len) > msg_hdr->msg_len ||
        msg_hdr->msg_len > dtls1_max_handshake_message_len(s))
        goto err;

    if (frag_len == 0)
        return DTLS1_HM_FRAGMENT_RETRY;

    /* Try to find item in queue */
    memset(seq64be, 0, sizeof(seq64be));
    seq64be[6] = (unsigned char)(msg_hdr->seq >> 8);
    seq64be[7] = (unsigned char)msg_hdr->seq;
    item = pqueue_find(s->d1->buffered_messages, seq64be);

    if (item == NULL) {
        frag = dtls1_hm_fragment_new(msg_hdr->msg_len, 1);
        if (frag == NULL)
            goto err;
        memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr));
        frag->msg_header.frag_len = frag->msg_header.msg_len;
        frag->msg_header.frag_off = 0;
    } else {
        frag = (hm_fragment *)item->data;
        if (frag->msg_header.msg_len != msg_hdr->msg_len) {
            item = NULL;
            frag = NULL;
            goto err;
        }
    }

    /*
     * If message is already reassembled, this must be a retransmit and can
     * be dropped. In this case item != NULL and so frag does not need to be
     * freed.
     */
    if (frag->reassembly == NULL) {
        unsigned char devnull[256];

        while (frag_len) {
557
            i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, NULL,
558 559 560 561 562 563 564 565 566 567 568 569
                                          devnull,
                                          frag_len >
                                          sizeof(devnull) ? sizeof(devnull) :
                                          frag_len, 0);
            if (i <= 0)
                goto err;
            frag_len -= i;
        }
        return DTLS1_HM_FRAGMENT_RETRY;
    }

    /* read the body of the fragment (header has already been read */
570
    i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, NULL,
571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608
                                  frag->fragment + msg_hdr->frag_off,
                                  frag_len, 0);
    if ((unsigned long)i != frag_len)
        i = -1;
    if (i <= 0)
        goto err;

    RSMBLY_BITMASK_MARK(frag->reassembly, (long)msg_hdr->frag_off,
                        (long)(msg_hdr->frag_off + frag_len));

    RSMBLY_BITMASK_IS_COMPLETE(frag->reassembly, (long)msg_hdr->msg_len,
                               is_complete);

    if (is_complete) {
        OPENSSL_free(frag->reassembly);
        frag->reassembly = NULL;
    }

    if (item == NULL) {
        item = pitem_new(seq64be, frag);
        if (item == NULL) {
            i = -1;
            goto err;
        }

        item = pqueue_insert(s->d1->buffered_messages, item);
        /*
         * pqueue_insert fails iff a duplicate item is inserted. However,
         * |item| cannot be a duplicate. If it were, |pqueue_find|, above,
         * would have returned it and control would never have reached this
         * branch.
         */
        OPENSSL_assert(item != NULL);
    }

    return DTLS1_HM_FRAGMENT_RETRY;

 err:
R
Rich Salz 已提交
609
    if (item == NULL)
610 611 612 613
        dtls1_hm_fragment_free(frag);
    *ok = 0;
    return i;
}
D
Dr. Stephen Henson 已提交
614

B
Ben Laurie 已提交
615
static int
616 617
dtls1_process_out_of_seq_message(SSL *s, const struct hm_header_st *msg_hdr,
                                 int *ok)
B
Ben Laurie 已提交
618
{
619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647
    int i = -1;
    hm_fragment *frag = NULL;
    pitem *item = NULL;
    unsigned char seq64be[8];
    unsigned long frag_len = msg_hdr->frag_len;

    if ((msg_hdr->frag_off + frag_len) > msg_hdr->msg_len)
        goto err;

    /* Try to find item in queue, to prevent duplicate entries */
    memset(seq64be, 0, sizeof(seq64be));
    seq64be[6] = (unsigned char)(msg_hdr->seq >> 8);
    seq64be[7] = (unsigned char)msg_hdr->seq;
    item = pqueue_find(s->d1->buffered_messages, seq64be);

    /*
     * If we already have an entry and this one is a fragment, don't discard
     * it and rather try to reassemble it.
     */
    if (item != NULL && frag_len != msg_hdr->msg_len)
        item = NULL;

    /*
     * Discard the message if sequence number was already there, is too far
     * in the future, already in the queue or if we received a FINISHED
     * before the SERVER_HELLO, which then must be a stale retransmit.
     */
    if (msg_hdr->seq <= s->d1->handshake_read_seq ||
        msg_hdr->seq > s->d1->handshake_read_seq + 10 || item != NULL ||
E
Emilia Kasper 已提交
648
        (s->d1->handshake_read_seq == 0 && msg_hdr->type == SSL3_MT_FINISHED)) {
649 650 651
        unsigned char devnull[256];

        while (frag_len) {
652
            i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, NULL,
653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677
                                          devnull,
                                          frag_len >
                                          sizeof(devnull) ? sizeof(devnull) :
                                          frag_len, 0);
            if (i <= 0)
                goto err;
            frag_len -= i;
        }
    } else {
        if (frag_len != msg_hdr->msg_len)
            return dtls1_reassemble_fragment(s, msg_hdr, ok);

        if (frag_len > dtls1_max_handshake_message_len(s))
            goto err;

        frag = dtls1_hm_fragment_new(frag_len, 0);
        if (frag == NULL)
            goto err;

        memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr));

        if (frag_len) {
            /*
             * read the body of the fragment (header has already been read
             */
678
            i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, NULL,
679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704
                                          frag->fragment, frag_len, 0);
            if ((unsigned long)i != frag_len)
                i = -1;
            if (i <= 0)
                goto err;
        }

        item = pitem_new(seq64be, frag);
        if (item == NULL)
            goto err;

        item = pqueue_insert(s->d1->buffered_messages, item);
        /*
         * pqueue_insert fails iff a duplicate item is inserted. However,
         * |item| cannot be a duplicate. If it were, |pqueue_find|, above,
         * would have returned it. Then, either |frag_len| !=
         * |msg_hdr->msg_len| in which case |item| is set to NULL and it will
         * have been processed with |dtls1_reassemble_fragment|, above, or
         * the record will have been discarded.
         */
        OPENSSL_assert(item != NULL);
    }

    return DTLS1_HM_FRAGMENT_RETRY;

 err:
R
Rich Salz 已提交
705
    if (item == NULL)
706 707 708 709
        dtls1_hm_fragment_free(frag);
    *ok = 0;
    return i;
}
B
Ben Laurie 已提交
710

711
static int dtls_get_reassembled_message(SSL *s, long *len)
712 713
{
    unsigned char wire[DTLS1_HM_HEADER_LENGTH];
714
    unsigned long mlen, frag_off, frag_len;
715
    int i, al, recvd_type;
716
    struct hm_header_st msg_hdr;
717
    int ok;
718 719 720

 redo:
    /* see if we have the required fragment already */
721 722
    if ((frag_len = dtls1_retrieve_buffered_fragment(s, &ok)) || ok) {
        if (ok)
723
            s->init_num = frag_len;
724 725
        *len = frag_len;
        return ok;
726 727 728
    }

    /* read handshake message header */
729
    i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, &recvd_type, wire,
730 731 732
                                  DTLS1_HM_HEADER_LENGTH, 0);
    if (i <= 0) {               /* nbio, or an error */
        s->rwstate = SSL_READING;
733 734
        *len = i;
        return 0;
735
    }
736
    if (recvd_type == SSL3_RT_CHANGE_CIPHER_SPEC) {
737 738 739 740 741
        if (wire[0] != SSL3_MT_CCS) {
            al = SSL_AD_UNEXPECTED_MESSAGE;
            SSLerr(SSL_F_DTLS_GET_REASSEMBLED_MESSAGE,
                   SSL_R_BAD_CHANGE_CIPHER_SPEC);
            goto f_err;
742
        }
743 744 745 746 747 748 749 750

        memcpy(s->init_buf->data, wire, i);
        s->init_num = i - 1;
        s->init_msg = s->init_buf->data + 1;
        s->s3->tmp.message_type = SSL3_MT_CHANGE_CIPHER_SPEC;
        s->s3->tmp.message_size = i - 1;
        *len = i - 1;
        return 1;
751 752
    }

753 754 755
    /* Handshake fails if message header is incomplete */
    if (i != DTLS1_HM_HEADER_LENGTH) {
        al = SSL_AD_UNEXPECTED_MESSAGE;
756
        SSLerr(SSL_F_DTLS_GET_REASSEMBLED_MESSAGE, SSL_R_UNEXPECTED_MESSAGE);
757 758 759 760 761 762
        goto f_err;
    }

    /* parse the message fragment header */
    dtls1_get_message_header(wire, &msg_hdr);

763
    mlen = msg_hdr.msg_len;
764 765 766 767 768 769 770 771 772
    frag_off = msg_hdr.frag_off;
    frag_len = msg_hdr.frag_len;

    /*
     * We must have at least frag_len bytes left in the record to be read.
     * Fragments must not span records.
     */
    if (frag_len > RECORD_LAYER_get_rrec_length(&s->rlayer)) {
        al = SSL3_AD_ILLEGAL_PARAMETER;
773
        SSLerr(SSL_F_DTLS_GET_REASSEMBLED_MESSAGE, SSL_R_BAD_LENGTH);
774 775 776
        goto f_err;
    }

777 778 779 780 781 782
    /*
     * if this is a future (or stale) message it gets buffered
     * (or dropped)--no further processing at this time
     * While listening, we accept seq 1 (ClientHello with cookie)
     * although we're still expecting seq 0 (ClientHello)
     */
783 784 785 786
    if (msg_hdr.seq != s->d1->handshake_read_seq) {
        *len = dtls1_process_out_of_seq_message(s, &msg_hdr, &ok);
        return ok;
    }
787

788 789 790 791
    if (frag_len && frag_len < mlen) {
        *len = dtls1_reassemble_fragment(s, &msg_hdr, &ok);
        return ok;
    }
792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807

    if (!s->server && s->d1->r_msg_hdr.frag_off == 0 &&
        wire[0] == SSL3_MT_HELLO_REQUEST) {
        /*
         * The server may always send 'Hello Request' messages -- we are
         * doing a handshake anyway now, so ignore them if their format is
         * correct. Does not count for 'Finished' MAC.
         */
        if (wire[1] == 0 && wire[2] == 0 && wire[3] == 0) {
            if (s->msg_callback)
                s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE,
                                wire, DTLS1_HM_HEADER_LENGTH, s,
                                s->msg_callback_arg);

            s->init_num = 0;
            goto redo;
808
        } else {                /* Incorrectly formatted Hello request */
809 810

            al = SSL_AD_UNEXPECTED_MESSAGE;
811
            SSLerr(SSL_F_DTLS_GET_REASSEMBLED_MESSAGE,
812 813 814 815 816
                   SSL_R_UNEXPECTED_MESSAGE);
            goto f_err;
        }
    }

817
    if ((al = dtls1_preprocess_fragment(s, &msg_hdr)))
818 819 820 821 822 823
        goto f_err;

    if (frag_len > 0) {
        unsigned char *p =
            (unsigned char *)s->init_buf->data + DTLS1_HM_HEADER_LENGTH;

824
        i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, NULL,
825
                                      &p[frag_off], frag_len, 0);
826

827
        /*
828 829
         * This shouldn't ever fail due to NBIO because we already checked
         * that we have enough data in the record
830 831 832
         */
        if (i <= 0) {
            s->rwstate = SSL_READING;
833 834
            *len = i;
            return 0;
835 836 837 838 839 840 841 842 843 844
        }
    } else
        i = 0;

    /*
     * XDTLS: an incorrectly formatted fragment should cause the handshake
     * to fail
     */
    if (i != (int)frag_len) {
        al = SSL3_AD_ILLEGAL_PARAMETER;
845
        SSLerr(SSL_F_DTLS_GET_REASSEMBLED_MESSAGE, SSL3_AD_ILLEGAL_PARAMETER);
846 847 848 849 850 851 852 853 854
        goto f_err;
    }

    /*
     * Note that s->init_num is *not* used as current offset in
     * s->init_buf->data, but as a counter summing up fragments' lengths: as
     * soon as they sum up to handshake packet length, we assume we have got
     * all the fragments.
     */
855 856
    *len = s->init_num = frag_len;
    return 1;
857 858 859 860

 f_err:
    ssl3_send_alert(s, SSL3_AL_FATAL, al);
    s->init_num = 0;
861 862
    *len = -1;
    return 0;
863
}
B
Ben Laurie 已提交
864

865 866
/*-
 * for these 2 messages, we need to
867
 * ssl->enc_read_ctx                    re-init
868
 * ssl->rlayer.read_sequence            zero
869 870 871 872
 * ssl->s3->read_mac_secret             re-init
 * ssl->session->read_sym_enc           assign
 * ssl->session->read_compression       assign
 * ssl->session->read_hash              assign
B
Ben Laurie 已提交
873
 */
874
int dtls_construct_change_cipher_spec(SSL *s)
875 876
{
    unsigned char *p;
B
Ben Laurie 已提交
877

878 879 880 881 882 883 884 885 886 887
    p = (unsigned char *)s->init_buf->data;
    *p++ = SSL3_MT_CCS;
    s->d1->handshake_write_seq = s->d1->next_handshake_write_seq;
    s->init_num = DTLS1_CCS_HEADER_LENGTH;

    if (s->version == DTLS1_BAD_VER) {
        s->d1->next_handshake_write_seq++;
        s2n(s->d1->handshake_write_seq, p);
        s->init_num += 2;
    }
B
Ben Laurie 已提交
888

889
    s->init_off = 0;
B
Ben Laurie 已提交
890

891 892
    dtls1_set_message_header_int(s, SSL3_MT_CCS, 0,
                                 s->d1->handshake_write_seq, 0, 0);
B
Ben Laurie 已提交
893

894 895 896 897
    /* buffer the message to handle re-xmits */
    if (!dtls1_buffer_message(s, 1)) {
        SSLerr(SSL_F_DTLS_CONSTRUCT_CHANGE_CIPHER_SPEC, ERR_R_INTERNAL_ERROR);
        return 0;
898
    }
B
Ben Laurie 已提交
899

900 901 902 903
    return 1;
}

#ifndef OPENSSL_NO_SCTP
M
Matt Caswell 已提交
904
WORK_STATE dtls_wait_for_dry(SSL *s)
905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920
{
    int ret;

    /* read app data until dry event */
    ret = BIO_dgram_sctp_wait_for_dry(SSL_get_wbio(s));
    if (ret < 0)
        return WORK_ERROR;

    if (ret == 0) {
        s->s3->in_read_app_data = 2;
        s->rwstate = SSL_READING;
        BIO_clear_retry_flags(SSL_get_rbio(s));
        BIO_set_retry_read(SSL_get_rbio(s));
        return WORK_MORE_A;
    }
    return WORK_FINISHED_CONTINUE;
921
}
922
#endif
B
Ben Laurie 已提交
923 924

int dtls1_read_failed(SSL *s, int code)
925 926
{
    if (code > 0) {
927
        SSLerr(SSL_F_DTLS1_READ_FAILED, ERR_R_INTERNAL_ERROR);
928 929 930 931 932 933 934 935 936 937
        return 1;
    }

    if (!dtls1_is_timer_expired(s)) {
        /*
         * not a timeout, none of our business, let higher layers handle
         * this.  in fact it's probably an error
         */
        return code;
    }
D
Dr. Stephen Henson 已提交
938
#ifndef OPENSSL_NO_HEARTBEATS
939 940
    /* done, no need to send a retransmit */
    if (!SSL_in_init(s) && !s->tlsext_hb_pending)
D
Dr. Stephen Henson 已提交
941
#else
942 943
    /* done, no need to send a retransmit */
    if (!SSL_in_init(s))
D
Dr. Stephen Henson 已提交
944
#endif
945 946 947 948
    {
        BIO_set_flags(SSL_get_rbio(s), BIO_FLAGS_READ);
        return code;
    }
B
Ben Laurie 已提交
949

950 951
    return dtls1_handle_timeout(s);
}
B
Ben Laurie 已提交
952

953 954 955 956 957 958 959 960 961 962 963 964 965 966
int dtls1_get_queue_priority(unsigned short seq, int is_ccs)
{
    /*
     * The index of the retransmission queue actually is the message sequence
     * number, since the queue only contains messages of a single handshake.
     * However, the ChangeCipherSpec has no message sequence number and so
     * using only the sequence will result in the CCS and Finished having the
     * same index. To prevent this, the sequence number is multiplied by 2.
     * In case of a CCS 1 is subtracted. This does not only differ CSS and
     * Finished, it also maintains the order of the index (important for
     * priority queues) and fits in the unsigned short variable.
     */
    return seq * 2 - is_ccs;
}
B
Ben Laurie 已提交
967

968 969
int dtls1_retransmit_buffered_messages(SSL *s)
{
R
Rich Salz 已提交
970
    pqueue *sent = s->d1->sent_messages;
971 972 973 974 975 976 977 978 979 980 981 982
    piterator iter;
    pitem *item;
    hm_fragment *frag;
    int found = 0;

    iter = pqueue_iterator(sent);

    for (item = pqueue_next(&iter); item != NULL; item = pqueue_next(&iter)) {
        frag = (hm_fragment *)item->data;
        if (dtls1_retransmit_message(s, (unsigned short)
                                     dtls1_get_queue_priority
                                     (frag->msg_header.seq,
E
Emilia Kasper 已提交
983
                                      frag->msg_header.is_ccs), &found) <= 0)
984 985 986 987 988
            return -1;
    }

    return 1;
}
B
Ben Laurie 已提交
989

990 991 992 993 994 995 996 997 998 999 1000 1001 1002
int dtls1_buffer_message(SSL *s, int is_ccs)
{
    pitem *item;
    hm_fragment *frag;
    unsigned char seq64be[8];

    /*
     * this function is called immediately after a message has been
     * serialized
     */
    OPENSSL_assert(s->init_off == 0);

    frag = dtls1_hm_fragment_new(s->init_num, 0);
1003
    if (frag == NULL)
1004 1005 1006 1007 1008
        return 0;

    memcpy(frag->fragment, s->init_buf->data, s->init_num);

    if (is_ccs) {
M
Matt Caswell 已提交
1009
        /* For DTLS1_BAD_VER the header length is non-standard */
1010
        OPENSSL_assert(s->d1->w_msg_hdr.msg_len +
E
Emilia Kasper 已提交
1011 1012
                       ((s->version ==
                         DTLS1_BAD_VER) ? 3 : DTLS1_CCS_HEADER_LENGTH)
M
Matt Caswell 已提交
1013
                       == (unsigned int)s->init_num);
1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030
    } else {
        OPENSSL_assert(s->d1->w_msg_hdr.msg_len +
                       DTLS1_HM_HEADER_LENGTH == (unsigned int)s->init_num);
    }

    frag->msg_header.msg_len = s->d1->w_msg_hdr.msg_len;
    frag->msg_header.seq = s->d1->w_msg_hdr.seq;
    frag->msg_header.type = s->d1->w_msg_hdr.type;
    frag->msg_header.frag_off = 0;
    frag->msg_header.frag_len = s->d1->w_msg_hdr.msg_len;
    frag->msg_header.is_ccs = is_ccs;

    /* save current state */
    frag->msg_header.saved_retransmit_state.enc_write_ctx = s->enc_write_ctx;
    frag->msg_header.saved_retransmit_state.write_hash = s->write_hash;
    frag->msg_header.saved_retransmit_state.compress = s->compress;
    frag->msg_header.saved_retransmit_state.session = s->session;
1031 1032
    frag->msg_header.saved_retransmit_state.epoch =
        DTLS_RECORD_LAYER_get_w_epoch(&s->rlayer);
1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048

    memset(seq64be, 0, sizeof(seq64be));
    seq64be[6] =
        (unsigned
         char)(dtls1_get_queue_priority(frag->msg_header.seq,
                                        frag->msg_header.is_ccs) >> 8);
    seq64be[7] =
        (unsigned
         char)(dtls1_get_queue_priority(frag->msg_header.seq,
                                        frag->msg_header.is_ccs));

    item = pitem_new(seq64be, frag);
    if (item == NULL) {
        dtls1_hm_fragment_free(frag);
        return 0;
    }
B
Ben Laurie 已提交
1049

1050 1051 1052
    pqueue_insert(s->d1->sent_messages, item);
    return 1;
}
B
Ben Laurie 已提交
1053

E
Emilia Kasper 已提交
1054
int dtls1_retransmit_message(SSL *s, unsigned short seq, int *found)
1055 1056 1057 1058 1059 1060 1061 1062 1063
{
    int ret;
    /* XDTLS: for now assuming that read/writes are blocking */
    pitem *item;
    hm_fragment *frag;
    unsigned long header_length;
    unsigned char seq64be[8];
    struct dtls1_retransmit_state saved_state;

1064 1065 1066 1067
    /*-
      OPENSSL_assert(s->init_num == 0);
      OPENSSL_assert(s->init_off == 0);
     */
1068 1069 1070 1071 1072 1073 1074 1075

    /* XDTLS:  the requested message ought to be found, otherwise error */
    memset(seq64be, 0, sizeof(seq64be));
    seq64be[6] = (unsigned char)(seq >> 8);
    seq64be[7] = (unsigned char)seq;

    item = pqueue_find(s->d1->sent_messages, seq64be);
    if (item == NULL) {
1076
        SSLerr(SSL_F_DTLS1_RETRANSMIT_MESSAGE, ERR_R_INTERNAL_ERROR);
1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102
        *found = 0;
        return 0;
    }

    *found = 1;
    frag = (hm_fragment *)item->data;

    if (frag->msg_header.is_ccs)
        header_length = DTLS1_CCS_HEADER_LENGTH;
    else
        header_length = DTLS1_HM_HEADER_LENGTH;

    memcpy(s->init_buf->data, frag->fragment,
           frag->msg_header.msg_len + header_length);
    s->init_num = frag->msg_header.msg_len + header_length;

    dtls1_set_message_header_int(s, frag->msg_header.type,
                                 frag->msg_header.msg_len,
                                 frag->msg_header.seq, 0,
                                 frag->msg_header.frag_len);

    /* save current state */
    saved_state.enc_write_ctx = s->enc_write_ctx;
    saved_state.write_hash = s->write_hash;
    saved_state.compress = s->compress;
    saved_state.session = s->session;
1103
    saved_state.epoch = DTLS_RECORD_LAYER_get_w_epoch(&s->rlayer);
1104 1105 1106 1107 1108 1109 1110 1111

    s->d1->retransmitting = 1;

    /* restore state in which the message was originally sent */
    s->enc_write_ctx = frag->msg_header.saved_retransmit_state.enc_write_ctx;
    s->write_hash = frag->msg_header.saved_retransmit_state.write_hash;
    s->compress = frag->msg_header.saved_retransmit_state.compress;
    s->session = frag->msg_header.saved_retransmit_state.session;
1112
    DTLS_RECORD_LAYER_set_saved_w_epoch(&s->rlayer,
E
Emilia Kasper 已提交
1113 1114
                                        frag->msg_header.
                                        saved_retransmit_state.epoch);
1115 1116 1117 1118 1119 1120 1121 1122 1123

    ret = dtls1_do_write(s, frag->msg_header.is_ccs ?
                         SSL3_RT_CHANGE_CIPHER_SPEC : SSL3_RT_HANDSHAKE);

    /* restore current state */
    s->enc_write_ctx = saved_state.enc_write_ctx;
    s->write_hash = saved_state.write_hash;
    s->compress = saved_state.compress;
    s->session = saved_state.session;
1124
    DTLS_RECORD_LAYER_set_saved_w_epoch(&s->rlayer, saved_state.epoch);
1125 1126 1127

    s->d1->retransmitting = 0;

1128
    (void)BIO_flush(s->wbio);
1129 1130
    return ret;
}
B
Ben Laurie 已提交
1131

1132 1133
void dtls1_set_message_header(SSL *s,
                              unsigned char mt, unsigned long len,
E
Emilia Kasper 已提交
1134
                              unsigned long frag_off, unsigned long frag_len)
1135
{
M
Matt Caswell 已提交
1136
    if (frag_off == 0) {
1137 1138 1139
        s->d1->handshake_write_seq = s->d1->next_handshake_write_seq;
        s->d1->next_handshake_write_seq++;
    }
A
Andy Polyakov 已提交
1140

1141 1142 1143
    dtls1_set_message_header_int(s, mt, len, s->d1->handshake_write_seq,
                                 frag_off, frag_len);
}
B
Ben Laurie 已提交
1144 1145 1146 1147

/* don't actually do the writing, wait till the MTU has been retrieved */
static void
dtls1_set_message_header_int(SSL *s, unsigned char mt,
1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158
                             unsigned long len, unsigned short seq_num,
                             unsigned long frag_off, unsigned long frag_len)
{
    struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr;

    msg_hdr->type = mt;
    msg_hdr->msg_len = len;
    msg_hdr->seq = seq_num;
    msg_hdr->frag_off = frag_off;
    msg_hdr->frag_len = frag_len;
}
B
Ben Laurie 已提交
1159 1160

static void
E
Emilia Kasper 已提交
1161
dtls1_fix_message_header(SSL *s, unsigned long frag_off, unsigned long frag_len)
1162 1163
{
    struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr;
B
Ben Laurie 已提交
1164

1165 1166 1167
    msg_hdr->frag_off = frag_off;
    msg_hdr->frag_len = frag_len;
}
A
Andy Polyakov 已提交
1168

1169 1170 1171
static unsigned char *dtls1_write_message_header(SSL *s, unsigned char *p)
{
    struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr;
A
Andy Polyakov 已提交
1172

1173 1174
    *p++ = msg_hdr->type;
    l2n3(msg_hdr->msg_len, p);
A
Andy Polyakov 已提交
1175

1176 1177 1178
    s2n(msg_hdr->seq, p);
    l2n3(msg_hdr->frag_off, p);
    l2n3(msg_hdr->frag_len, p);
B
Ben Laurie 已提交
1179

1180 1181
    return p;
}
B
Ben Laurie 已提交
1182

E
Emilia Kasper 已提交
1183
void dtls1_get_message_header(unsigned char *data, struct hm_header_st *msg_hdr)
1184
{
1185
    memset(msg_hdr, 0, sizeof(*msg_hdr));
1186 1187
    msg_hdr->type = *(data++);
    n2l3(data, msg_hdr->msg_len);
A
Andy Polyakov 已提交
1188

1189 1190 1191 1192
    n2s(data, msg_hdr->seq);
    n2l3(data, msg_hdr->frag_off);
    n2l3(data, msg_hdr->frag_len);
}
1193 1194

/*
M
Matt Caswell 已提交
1195
 * Temporary name. To be renamed dtls1_set_handshake_header() once all WPACKET
1196 1197 1198 1199
 * conversion is complete. The old dtls1_set_handshake_heder() can be deleted
 * at that point.
 * TODO - RENAME ME
 */
1200
int dtls1_set_handshake_header2(SSL *s, WPACKET *pkt, int htype)
1201 1202
{
    unsigned char *header;
M
Matt Caswell 已提交
1203

1204 1205 1206 1207 1208 1209
    dtls1_set_message_header(s, htype, 0, 0, 0);

    /*
     * We allocate space at the start for the message header. This gets filled
     * in later
     */
M
Matt Caswell 已提交
1210
    if (!WPACKET_allocate_bytes(pkt, DTLS1_HM_HEADER_LENGTH, &header)
1211
            || !WPACKET_start_sub_packet(pkt))
1212 1213 1214 1215 1216
        return 0;

    return 1;
}

M
Matt Caswell 已提交
1217
int dtls1_close_construct_packet(SSL *s, WPACKET *pkt)
1218 1219 1220
{
    size_t msglen;

1221 1222
    if (!WPACKET_close(pkt)
            || !WPACKET_get_length(pkt, &msglen)
1223
            || msglen > INT_MAX
1224
            || !WPACKET_finish(pkt))
1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236
        return 0;
    s->d1->w_msg_hdr.msg_len = msglen - DTLS1_HM_HEADER_LENGTH;
    s->d1->w_msg_hdr.frag_len = msglen - DTLS1_HM_HEADER_LENGTH;
    s->init_num = (int)msglen;
    s->init_off = 0;

    /* Buffer the message to handle re-xmits */
    if (!dtls1_buffer_message(s, 0))
        return 0;

    return 1;
}