/*
 * 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 (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.] */

#include <openssl/ssl.h>

#include <assert.h>
#include <limits.h>
#include <string.h>

#include <openssl/buf.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/mem.h>
#include <openssl/obj.h>
#include <openssl/rand.h>
#include <openssl/x509.h>

#include "internal.h"


/* TODO(davidben): 28 comes from the size of IP + UDP header. Is this reasonable
 * for these values? Notably, why is kMinMTU a function of the transport
 * protocol's overhead rather than, say, what's needed to hold a minimally-sized
 * handshake fragment plus protocol overhead. */

/* kMinMTU is the minimum acceptable MTU value. */
static const unsigned int kMinMTU = 256 - 28;

/* kDefaultMTU is the default MTU value to use if neither the user nor
 * the underlying BIO supplies one. */
static const unsigned int kDefaultMTU = 1500 - 28;

/* kMaxHandshakeBuffer is the maximum number of handshake messages ahead of the
 * current one to buffer. */
static const unsigned int kHandshakeBufferSize = 10;

static hm_fragment *dtls1_hm_fragment_new(size_t frag_len, int reassembly) {
  hm_fragment *frag = OPENSSL_malloc(sizeof(hm_fragment));
  if (frag == NULL) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
    return NULL;
  }
  memset(frag, 0, sizeof(hm_fragment));

  /* If the handshake message is empty, |frag->fragment| and |frag->reassembly|
   * are NULL. */
  if (frag_len > 0) {
    frag->fragment = OPENSSL_malloc(frag_len);
    if (frag->fragment == NULL) {
      OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
      goto err;
    }

    if (reassembly) {
      /* Initialize reassembly bitmask. */
      if (frag_len + 7 < frag_len) {
        OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
        goto err;
      }
      size_t bitmask_len = (frag_len + 7) / 8;
      frag->reassembly = OPENSSL_malloc(bitmask_len);
      if (frag->reassembly == NULL) {
        OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
        goto err;
      }
      memset(frag->reassembly, 0, bitmask_len);
    }
  }

  return frag;

err:
  dtls1_hm_fragment_free(frag);
  return NULL;
}

void dtls1_hm_fragment_free(hm_fragment *frag) {
  if (frag == NULL) {
    return;
  }
  OPENSSL_free(frag->fragment);
  OPENSSL_free(frag->reassembly);
  OPENSSL_free(frag);
}

#if !defined(inline)
#define inline __inline
#endif

/* bit_range returns a |uint8_t| with bits |start|, inclusive, to |end|,
 * exclusive, set. */
static inline uint8_t bit_range(size_t start, size_t end) {
  return (uint8_t)(~((1u << start) - 1) & ((1u << end) - 1));
}

/* dtls1_hm_fragment_mark marks bytes |start|, inclusive, to |end|, exclusive,
 * as received in |frag|. If |frag| becomes complete, it clears
 * |frag->reassembly|. The range must be within the bounds of |frag|'s message
 * and |frag->reassembly| must not be NULL. */
static void dtls1_hm_fragment_mark(hm_fragment *frag, size_t start,
                                   size_t end) {
  size_t i;
  size_t msg_len = frag->msg_header.msg_len;

  if (frag->reassembly == NULL || start > end || end > msg_len) {
    assert(0);
    return;
  }
  /* A zero-length message will never have a pending reassembly. */
  assert(msg_len > 0);

  if ((start >> 3) == (end >> 3)) {
    frag->reassembly[start >> 3] |= bit_range(start & 7, end & 7);
  } else {
    frag->reassembly[start >> 3] |= bit_range(start & 7, 8);
    for (i = (start >> 3) + 1; i < (end >> 3); i++) {
      frag->reassembly[i] = 0xff;
    }
    if ((end & 7) != 0) {
      frag->reassembly[end >> 3] |= bit_range(0, end & 7);
    }
  }

  /* Check if the fragment is complete. */
  for (i = 0; i < (msg_len >> 3); i++) {
    if (frag->reassembly[i] != 0xff) {
      return;
    }
  }
  if ((msg_len & 7) != 0 &&
      frag->reassembly[msg_len >> 3] != bit_range(0, msg_len & 7)) {
    return;
  }

  OPENSSL_free(frag->reassembly);
  frag->reassembly = NULL;
}

static void dtls1_update_mtu(SSL *ssl) {
  /* TODO(davidben): What is this code doing and do we need it? */
  if (ssl->d1->mtu < dtls1_min_mtu() &&
      !(SSL_get_options(ssl) & SSL_OP_NO_QUERY_MTU)) {
    long mtu = BIO_ctrl(SSL_get_wbio(ssl), BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL);
    if (mtu >= 0 && mtu <= (1 << 30) && (unsigned)mtu >= dtls1_min_mtu()) {
      ssl->d1->mtu = (unsigned)mtu;
    } else {
      ssl->d1->mtu = kDefaultMTU;
      BIO_ctrl(SSL_get_wbio(ssl), BIO_CTRL_DGRAM_SET_MTU, ssl->d1->mtu, NULL);
    }
  }

  /* The MTU should be above the minimum now. */
  assert(ssl->d1->mtu >= dtls1_min_mtu());
}

/* dtls1_max_record_size returns the maximum record body length that may be
 * written without exceeding the MTU. It accounts for any buffering installed on
 * the write BIO. If no record may be written, it returns zero. */
static size_t dtls1_max_record_size(SSL *ssl) {
  size_t ret = ssl->d1->mtu;

  size_t overhead = ssl_max_seal_overhead(ssl);
  if (ret <= overhead) {
    return 0;
  }
  ret -= overhead;

  size_t pending = BIO_wpending(SSL_get_wbio(ssl));
  if (ret <= pending) {
    return 0;
  }
  ret -= pending;

  return ret;
}

static int dtls1_write_change_cipher_spec(SSL *ssl,
                                          enum dtls1_use_epoch_t use_epoch) {
  dtls1_update_mtu(ssl);

  /* During the handshake, wbio is buffered to pack messages together. Flush the
   * buffer if the ChangeCipherSpec would not fit in a packet. */
  if (dtls1_max_record_size(ssl) == 0) {
    ssl->rwstate = SSL_WRITING;
    int ret = BIO_flush(SSL_get_wbio(ssl));
    if (ret <= 0) {
      return ret;
    }
    ssl->rwstate = SSL_NOTHING;
  }

  static const uint8_t kChangeCipherSpec[1] = {SSL3_MT_CCS};
  int ret =
      dtls1_write_bytes(ssl, SSL3_RT_CHANGE_CIPHER_SPEC, kChangeCipherSpec,
                        sizeof(kChangeCipherSpec), use_epoch);
  if (ret <= 0) {
    return ret;
  }

  if (ssl->msg_callback != NULL) {
    ssl->msg_callback(1 /* write */, ssl->version, SSL3_RT_CHANGE_CIPHER_SPEC,
                      kChangeCipherSpec, sizeof(kChangeCipherSpec), ssl,
                      ssl->msg_callback_arg);
  }

  return 1;
}

int dtls1_do_handshake_write(SSL *ssl, enum dtls1_use_epoch_t use_epoch) {
  dtls1_update_mtu(ssl);

  int ret = -1;
  CBB cbb;
  CBB_zero(&cbb);
  /* Allocate a temporary buffer to hold the message fragments to avoid
   * clobbering the message. */
  uint8_t *buf = OPENSSL_malloc(ssl->d1->mtu);
  if (buf == NULL) {
    goto err;
  }

  /* Consume the message header. Fragments will have different headers
   * prepended. */
  if (ssl->init_off == 0) {
    ssl->init_off += DTLS1_HM_HEADER_LENGTH;
    ssl->init_num -= DTLS1_HM_HEADER_LENGTH;
  }
  assert(ssl->init_off >= DTLS1_HM_HEADER_LENGTH);

  do {
    /* During the handshake, wbio is buffered to pack messages together. Flush
     * the buffer if there isn't enough room to make progress. */
    if (dtls1_max_record_size(ssl) < DTLS1_HM_HEADER_LENGTH + 1) {
      ssl->rwstate = SSL_WRITING;
      int flush_ret = BIO_flush(SSL_get_wbio(ssl));
      if (flush_ret <= 0) {
        ret = flush_ret;
        goto err;
      }
      ssl->rwstate = SSL_NOTHING;
      assert(BIO_wpending(SSL_get_wbio(ssl)) == 0);
    }

    size_t todo = dtls1_max_record_size(ssl);
    if (todo < DTLS1_HM_HEADER_LENGTH + 1) {
      /* To make forward progress, the MTU must, at minimum, fit the handshake
       * header and one byte of handshake body. */
      OPENSSL_PUT_ERROR(SSL, SSL_R_MTU_TOO_SMALL);
      goto err;
    }
    todo -= DTLS1_HM_HEADER_LENGTH;

    if (todo > (size_t)ssl->init_num) {
      todo = ssl->init_num;
    }
    if (todo >= (1u << 24)) {
      todo = (1u << 24) - 1;
    }

    size_t len;
    if (!CBB_init_fixed(&cbb, buf, ssl->d1->mtu) ||
        !CBB_add_u8(&cbb, ssl->d1->w_msg_hdr.type) ||
        !CBB_add_u24(&cbb, ssl->d1->w_msg_hdr.msg_len) ||
        !CBB_add_u16(&cbb, ssl->d1->w_msg_hdr.seq) ||
        !CBB_add_u24(&cbb, ssl->init_off - DTLS1_HM_HEADER_LENGTH) ||
        !CBB_add_u24(&cbb, todo) ||
        !CBB_add_bytes(
            &cbb, (const uint8_t *)ssl->init_buf->data + ssl->init_off, todo) ||
        !CBB_finish(&cbb, NULL, &len)) {
      OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
      goto err;
    }

    int write_ret = dtls1_write_bytes(ssl, SSL3_RT_HANDSHAKE, buf, len,
                                      use_epoch);
    if (write_ret <= 0) {
      ret = write_ret;
      goto err;
    }
    ssl->init_off += todo;
    ssl->init_num -= todo;
  } while (ssl->init_num > 0);

  if (ssl->msg_callback != NULL) {
    ssl->msg_callback(
        1 /* write */, ssl->version, SSL3_RT_HANDSHAKE, ssl->init_buf->data,
        (size_t)(ssl->init_off + ssl->init_num), ssl, ssl->msg_callback_arg);
  }

  ssl->init_off = 0;
  ssl->init_num = 0;

  ret = 1;

err:
  CBB_cleanup(&cbb);
  OPENSSL_free(buf);
  return ret;
}

/* dtls1_is_next_message_complete returns one if the next handshake message is
 * complete and zero otherwise. */
static int dtls1_is_next_message_complete(SSL *ssl) {
  pitem *item = pqueue_peek(ssl->d1->buffered_messages);
  if (item == NULL) {
    return 0;
  }

  hm_fragment *frag = (hm_fragment *)item->data;
  assert(ssl->d1->handshake_read_seq <= frag->msg_header.seq);

  return ssl->d1->handshake_read_seq == frag->msg_header.seq &&
         frag->reassembly == NULL;
}

/* dtls1_discard_fragment_body discards a handshake fragment body of length
 * |frag_len|. It returns one on success and zero on error.
 *
 * TODO(davidben): This function will go away when ssl_read_bytes is gone from
 * the DTLS side. */
static int dtls1_discard_fragment_body(SSL *ssl, size_t frag_len) {
  uint8_t discard[256];
  while (frag_len > 0) {
    size_t chunk = frag_len < sizeof(discard) ? frag_len : sizeof(discard);
    int ret = dtls1_read_bytes(ssl, SSL3_RT_HANDSHAKE, discard, chunk, 0);
    if (ret != (int) chunk) {
      return 0;
    }
    frag_len -= chunk;
  }
  return 1;
}

/* dtls1_get_buffered_message returns the buffered message corresponding to
 * |msg_hdr|. If none exists, it creates a new one and inserts it in the
 * queue. Otherwise, it checks |msg_hdr| is consistent with the existing one. It
 * returns NULL on failure. The caller does not take ownership of the result. */
static hm_fragment *dtls1_get_buffered_message(
    SSL *ssl, const struct hm_header_st *msg_hdr) {
  uint8_t seq64be[8];
  memset(seq64be, 0, sizeof(seq64be));
  seq64be[6] = (uint8_t)(msg_hdr->seq >> 8);
  seq64be[7] = (uint8_t)msg_hdr->seq;
  pitem *item = pqueue_find(ssl->d1->buffered_messages, seq64be);

  hm_fragment *frag;
  if (item == NULL) {
    /* This is the first fragment from this message. */
    frag = dtls1_hm_fragment_new(msg_hdr->msg_len,
                                 1 /* reassembly buffer needed */);
    if (frag == NULL) {
      return NULL;
    }
    memcpy(&frag->msg_header, msg_hdr, sizeof(*msg_hdr));
    item = pitem_new(seq64be, frag);
    if (item == NULL) {
      dtls1_hm_fragment_free(frag);
      return NULL;
    }
    item = pqueue_insert(ssl->d1->buffered_messages, item);
    /* |pqueue_insert| fails iff a duplicate item is inserted, but |item| cannot
     * be a duplicate. */
    assert(item != NULL);
  } else {
    frag = item->data;
    assert(frag->msg_header.seq == msg_hdr->seq);
    if (frag->msg_header.type != msg_hdr->type ||
        frag->msg_header.msg_len != msg_hdr->msg_len) {
      /* The new fragment must be compatible with the previous fragments from
       * this message. */
      OPENSSL_PUT_ERROR(SSL, SSL_R_FRAGMENT_MISMATCH);
      ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
      return NULL;
    }
  }
  return frag;
}

/* dtls1_max_handshake_message_len returns the maximum number of bytes
 * permitted in a DTLS handshake message for |ssl|. The minimum is 16KB, but may
 * be greater if the maximum certificate list size requires it. */
static size_t dtls1_max_handshake_message_len(const SSL *ssl) {
  size_t max_len = DTLS1_HM_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH;
  if (max_len < ssl->max_cert_list) {
    return ssl->max_cert_list;
  }
  return max_len;
}

/* dtls1_process_fragment reads a handshake fragment and processes it. It
 * returns one if a fragment was successfully processed and 0 or -1 on error. */
static int dtls1_process_fragment(SSL *ssl) {
  /* Read handshake message header. */
  uint8_t header[DTLS1_HM_HEADER_LENGTH];
  int ret = dtls1_read_bytes(ssl, SSL3_RT_HANDSHAKE, header,
                             DTLS1_HM_HEADER_LENGTH, 0);
  if (ret <= 0) {
    return ret;
  }
  if (ret != DTLS1_HM_HEADER_LENGTH) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE);
    ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
    return -1;
  }

  /* Parse the message fragment header. */
  struct hm_header_st msg_hdr;
  dtls1_get_message_header(header, &msg_hdr);

  /* TODO(davidben): dtls1_read_bytes is the wrong abstraction for DTLS. There
   * should be no need to reach into |ssl->s3->rrec.length|. */
  const size_t frag_off = msg_hdr.frag_off;
  const size_t frag_len = msg_hdr.frag_len;
  const size_t msg_len = msg_hdr.msg_len;
  if (frag_off > msg_len || frag_off + frag_len < frag_off ||
      frag_off + frag_len > msg_len ||
      msg_len > dtls1_max_handshake_message_len(ssl) ||
      frag_len > ssl->s3->rrec.length) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_EXCESSIVE_MESSAGE_SIZE);
    ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
    return -1;
  }

  if (msg_hdr.seq < ssl->d1->handshake_read_seq ||
      msg_hdr.seq > (unsigned)ssl->d1->handshake_read_seq +
                    kHandshakeBufferSize) {
    /* Ignore fragments from the past, or ones too far in the future. */
    if (!dtls1_discard_fragment_body(ssl, frag_len)) {
      return -1;
    }
    return 1;
  }

  hm_fragment *frag = dtls1_get_buffered_message(ssl, &msg_hdr);
  if (frag == NULL) {
    return -1;
  }
  assert(frag->msg_header.msg_len == msg_len);

  if (frag->reassembly == NULL) {
    /* The message is already assembled. */
    if (!dtls1_discard_fragment_body(ssl, frag_len)) {
      return -1;
    }
    return 1;
  }
  assert(msg_len > 0);

  /* Read the body of the fragment. */
  ret = dtls1_read_bytes(ssl, SSL3_RT_HANDSHAKE, frag->fragment + frag_off,
                         frag_len, 0);
  if (ret != (int) frag_len) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
    ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
    return -1;
  }
  dtls1_hm_fragment_mark(frag, frag_off, frag_off + frag_len);

  return 1;
}

/* dtls1_get_message reads a handshake message of message type |msg_type| (any
 * if |msg_type| == -1), maximum acceptable body length |max|. Read an entire
 * handshake message. Handshake messages arrive in fragments. */
long dtls1_get_message(SSL *ssl, int st1, int stn, int msg_type, long max,
                       enum ssl_hash_message_t hash_message, int *ok) {
  pitem *item = NULL;
  hm_fragment *frag = NULL;
  int al;

  /* s3->tmp is used to store messages that are unexpected, caused
   * by the absence of an optional handshake message */
  if (ssl->s3->tmp.reuse_message) {
    /* A ssl_dont_hash_message call cannot be combined with reuse_message; the
     * ssl_dont_hash_message would have to have been applied to the previous
     * call. */
    assert(hash_message == ssl_hash_message);
    ssl->s3->tmp.reuse_message = 0;
    if (msg_type >= 0 && ssl->s3->tmp.message_type != msg_type) {
      al = SSL_AD_UNEXPECTED_MESSAGE;
      OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE);
      goto f_err;
    }
    *ok = 1;
    ssl->init_msg = (uint8_t *)ssl->init_buf->data + DTLS1_HM_HEADER_LENGTH;
    ssl->init_num = (int)ssl->s3->tmp.message_size;
    return ssl->init_num;
  }

  /* Process fragments until one is found. */
  while (!dtls1_is_next_message_complete(ssl)) {
    int ret = dtls1_process_fragment(ssl);
    if (ret <= 0) {
      *ok = 0;
      return ret;
    }
  }

  /* Read out the next complete handshake message. */
  item = pqueue_pop(ssl->d1->buffered_messages);
  assert(item != NULL);
  frag = (hm_fragment *)item->data;
  assert(ssl->d1->handshake_read_seq == frag->msg_header.seq);
  assert(frag->reassembly == NULL);

  if (frag->msg_header.msg_len > (size_t)max) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_EXCESSIVE_MESSAGE_SIZE);
    goto err;
  }

  /* Reconstruct the assembled message. */
  size_t len;
  CBB cbb;
  CBB_zero(&cbb);
  if (!BUF_MEM_grow(ssl->init_buf, (size_t)frag->msg_header.msg_len +
                                       DTLS1_HM_HEADER_LENGTH) ||
      !CBB_init_fixed(&cbb, (uint8_t *)ssl->init_buf->data,
                      ssl->init_buf->max) ||
      !CBB_add_u8(&cbb, frag->msg_header.type) ||
      !CBB_add_u24(&cbb, frag->msg_header.msg_len) ||
      !CBB_add_u16(&cbb, frag->msg_header.seq) ||
      !CBB_add_u24(&cbb, 0 /* frag_off */) ||
      !CBB_add_u24(&cbb, frag->msg_header.msg_len) ||
      !CBB_add_bytes(&cbb, frag->fragment, frag->msg_header.msg_len) ||
      !CBB_finish(&cbb, NULL, &len)) {
    CBB_cleanup(&cbb);
    OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
    goto err;
  }
  assert(len == (size_t)frag->msg_header.msg_len + DTLS1_HM_HEADER_LENGTH);

  ssl->d1->handshake_read_seq++;

  /* TODO(davidben): This function has a lot of implicit outputs. Simplify the
   * |ssl_get_message| API. */
  ssl->s3->tmp.message_type = frag->msg_header.type;
  ssl->s3->tmp.message_size = frag->msg_header.msg_len;
  ssl->init_msg = (uint8_t *)ssl->init_buf->data + DTLS1_HM_HEADER_LENGTH;
  ssl->init_num = frag->msg_header.msg_len;

  if (msg_type >= 0 && ssl->s3->tmp.message_type != msg_type) {
    al = SSL_AD_UNEXPECTED_MESSAGE;
    OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE);
    goto f_err;
  }
  if (hash_message == ssl_hash_message && !ssl3_hash_current_message(ssl)) {
    goto err;
  }
  if (ssl->msg_callback) {
    ssl->msg_callback(0, ssl->version, SSL3_RT_HANDSHAKE, ssl->init_buf->data,
                    ssl->init_num + DTLS1_HM_HEADER_LENGTH, ssl,
                    ssl->msg_callback_arg);
  }

  pitem_free(item);
  dtls1_hm_fragment_free(frag);

  ssl->state = stn;
  *ok = 1;
  return ssl->init_num;

f_err:
  ssl3_send_alert(ssl, SSL3_AL_FATAL, al);
err:
  pitem_free(item);
  dtls1_hm_fragment_free(frag);
  *ok = 0;
  return -1;
}

int dtls1_read_failed(SSL *ssl, int code) {
  if (code > 0) {
    assert(0);
    return 1;
  }

  if (!dtls1_is_timer_expired(ssl)) {
    /* not a timeout, none of our business, let higher layers handle this. In
     * fact, it's probably an error */
    return code;
  }

  if (!SSL_in_init(ssl)) {
    /* done, no need to send a retransmit */
    BIO_set_flags(SSL_get_rbio(ssl), BIO_FLAGS_READ);
    return code;
  }

  return DTLSv1_handle_timeout(ssl);
}

static uint16_t dtls1_get_queue_priority(uint16_t seq, int is_ccs) {
  assert(seq * 2 >= seq);

  /* 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;
}

static int dtls1_retransmit_message(SSL *ssl, hm_fragment *frag) {
  /* DTLS renegotiation is unsupported, so only epochs 0 (NULL cipher) and 1
   * (negotiated cipher) exist. */
  assert(ssl->d1->w_epoch == 0 || ssl->d1->w_epoch == 1);
  assert(frag->msg_header.epoch <= ssl->d1->w_epoch);
  enum dtls1_use_epoch_t use_epoch = dtls1_use_current_epoch;
  if (ssl->d1->w_epoch == 1 && frag->msg_header.epoch == 0) {
    use_epoch = dtls1_use_previous_epoch;
  }

  /* TODO(davidben): This cannot handle non-blocking writes. */
  int ret;
  if (frag->msg_header.is_ccs) {
    ret = dtls1_write_change_cipher_spec(ssl, use_epoch);
  } else {
    /* Restore the message body.
     * TODO(davidben): Make this less stateful. */
    memcpy(ssl->init_buf->data, frag->fragment,
           frag->msg_header.msg_len + DTLS1_HM_HEADER_LENGTH);
    ssl->init_num = frag->msg_header.msg_len + DTLS1_HM_HEADER_LENGTH;

    dtls1_set_message_header(ssl, frag->msg_header.type,
                             frag->msg_header.msg_len, frag->msg_header.seq,
                             0, frag->msg_header.frag_len);
    ret = dtls1_do_handshake_write(ssl, use_epoch);
  }

  /* TODO(davidben): Check return value? */
  (void)BIO_flush(SSL_get_wbio(ssl));
  return ret;
}


int dtls1_retransmit_buffered_messages(SSL *ssl) {
  pqueue sent = ssl->d1->sent_messages;
  piterator iter = pqueue_iterator(sent);
  pitem *item;

  for (item = pqueue_next(&iter); item != NULL; item = pqueue_next(&iter)) {
    hm_fragment *frag = (hm_fragment *)item->data;
    if (dtls1_retransmit_message(ssl, frag) <= 0) {
      return -1;
    }
  }

  return 1;
}

/* dtls1_buffer_change_cipher_spec adds a ChangeCipherSpec to the current
 * handshake flight, ordered just before the handshake message numbered
 * |seq|. */
static int dtls1_buffer_change_cipher_spec(SSL *ssl, uint16_t seq) {
  hm_fragment *frag = dtls1_hm_fragment_new(0 /* frag_len */,
                                            0 /* no reassembly */);
  if (frag == NULL) {
    return 0;
  }
  frag->msg_header.is_ccs = 1;
  frag->msg_header.epoch = ssl->d1->w_epoch;

  uint16_t priority = dtls1_get_queue_priority(seq, 1 /* is_ccs */);
  uint8_t seq64be[8];
  memset(seq64be, 0, sizeof(seq64be));
  seq64be[6] = (uint8_t)(priority >> 8);
  seq64be[7] = (uint8_t)priority;

  pitem *item = pitem_new(seq64be, frag);
  if (item == NULL) {
    dtls1_hm_fragment_free(frag);
    return 0;
  }

  pqueue_insert(ssl->d1->sent_messages, item);
  return 1;
}

int dtls1_buffer_message(SSL *ssl) {
  /* this function is called immediately after a message has
   * been serialized */
  assert(ssl->init_off == 0);

  hm_fragment *frag = dtls1_hm_fragment_new(ssl->init_num, 0);
  if (!frag) {
    return 0;
  }

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

  assert(ssl->d1->w_msg_hdr.msg_len + DTLS1_HM_HEADER_LENGTH ==
         (unsigned int)ssl->init_num);

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

  uint16_t priority = dtls1_get_queue_priority(frag->msg_header.seq,
                                               0 /* handshake */);
  uint8_t seq64be[8];
  memset(seq64be, 0, sizeof(seq64be));
  seq64be[6] = (uint8_t)(priority >> 8);
  seq64be[7] = (uint8_t)priority;

  pitem *item = pitem_new(seq64be, frag);
  if (item == NULL) {
    dtls1_hm_fragment_free(frag);
    return 0;
  }

  pqueue_insert(ssl->d1->sent_messages, item);
  return 1;
}

int dtls1_send_change_cipher_spec(SSL *ssl, int a, int b) {
  if (ssl->state == a) {
    /* Buffer the message to handle retransmits. */
    ssl->d1->handshake_write_seq = ssl->d1->next_handshake_write_seq;
    dtls1_buffer_change_cipher_spec(ssl, ssl->d1->handshake_write_seq);
    ssl->state = b;
  }

  return dtls1_write_change_cipher_spec(ssl, dtls1_use_current_epoch);
}

/* call this function when the buffered messages are no longer needed */
void dtls1_clear_record_buffer(SSL *ssl) {
  pitem *item;

  for (item = pqueue_pop(ssl->d1->sent_messages); item != NULL;
       item = pqueue_pop(ssl->d1->sent_messages)) {
    dtls1_hm_fragment_free((hm_fragment *)item->data);
    pitem_free(item);
  }
}

/* don't actually do the writing, wait till the MTU has been retrieved */
void dtls1_set_message_header(SSL *ssl, uint8_t mt, unsigned long len,
                              unsigned short seq_num, unsigned long frag_off,
                              unsigned long frag_len) {
  struct hm_header_st *msg_hdr = &ssl->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;
}

unsigned int dtls1_min_mtu(void) {
  return kMinMTU;
}

void dtls1_get_message_header(uint8_t *data,
                              struct hm_header_st *msg_hdr) {
  memset(msg_hdr, 0x00, sizeof(struct hm_header_st));
  msg_hdr->type = *(data++);
  n2l3(data, msg_hdr->msg_len);

  n2s(data, msg_hdr->seq);
  n2l3(data, msg_hdr->frag_off);
  n2l3(data, msg_hdr->frag_len);
}
