/* 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.]
 */
/* ====================================================================
 * Copyright (c) 1998-2007 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 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
 *
 * Portions of the attached software ("Contribution") are developed by 
 * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
 *
 * The Contribution is licensed pursuant to the OpenSSL open source
 * license provided above.
 *
 * ECC cipher suite support in OpenSSL originally written by
 * Vipul Gupta and Sumit Gupta of Sun Microsystems Laboratories.
 *
 */
/* ====================================================================
 * Copyright 2005 Nokia. All rights reserved.
 *
 * The portions of the attached software ("Contribution") is developed by
 * Nokia Corporation and is licensed pursuant to the OpenSSL open source
 * license.
 *
 * The Contribution, originally written by Mika Kousa and Pasi Eronen of
 * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
 * support (see RFC 4279) to OpenSSL.
 *
 * No patent licenses or other rights except those expressly stated in
 * the OpenSSL open source license shall be deemed granted or received
 * expressly, by implication, estoppel, or otherwise.
 *
 * No assurances are provided by Nokia that the Contribution does not
 * infringe the patent or other intellectual property rights of any third
 * party or that the license provides you with all the necessary rights
 * to make use of the Contribution.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
 * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
 * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
 * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
 * OTHERWISE. */

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

#include <openssl/bn.h>
#include <openssl/buf.h>
#include <openssl/bytestring.h>
#include <openssl/cipher.h>
#include <openssl/dh.h>
#include <openssl/ec.h>
#include <openssl/ecdsa.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/hmac.h>
#include <openssl/md5.h>
#include <openssl/mem.h>
#include <openssl/obj.h>
#include <openssl/rand.h>
#include <openssl/sha.h>
#include <openssl/x509.h>

#include "internal.h"
#include "../crypto/internal.h"
#include "../crypto/dh/internal.h"


/* INITIAL_SNIFF_BUFFER_SIZE is the number of bytes read in the initial sniff
 * buffer. */
#define INITIAL_SNIFF_BUFFER_SIZE 8

int ssl3_accept(SSL *s) {
  BUF_MEM *buf = NULL;
  uint32_t alg_a;
  void (*cb)(const SSL *ssl, int type, int val) = NULL;
  int ret = -1;
  int new_state, state, skip = 0;

  assert(s->handshake_func == ssl3_accept);
  assert(s->server);
  assert(!SSL_IS_DTLS(s));

  ERR_clear_error();
  ERR_clear_system_error();

  if (s->info_callback != NULL) {
    cb = s->info_callback;
  } else if (s->ctx->info_callback != NULL) {
    cb = s->ctx->info_callback;
  }

  s->in_handshake++;

  if (s->cert == NULL) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATE_SET);
    return -1;
  }

  for (;;) {
    state = s->state;

    switch (s->state) {
      case SSL_ST_ACCEPT:
        if (cb != NULL) {
          cb(s, SSL_CB_HANDSHAKE_START, 1);
        }

        if (s->init_buf == NULL) {
          buf = BUF_MEM_new();
          if (!buf || !BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) {
            ret = -1;
            goto end;
          }
          s->init_buf = buf;
          buf = NULL;
        }
        s->init_num = 0;

        /* Enable a write buffer. This groups handshake messages within a flight
         * into a single write. */
        if (!ssl_init_wbio_buffer(s, 1)) {
          ret = -1;
          goto end;
        }

        if (!ssl3_init_finished_mac(s)) {
          OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
          ret = -1;
          goto end;
        }

        if (!s->s3->have_version) {
          s->state = SSL3_ST_SR_INITIAL_BYTES;
        } else {
          s->state = SSL3_ST_SR_CLNT_HELLO_A;
        }
        break;

      case SSL3_ST_SR_INITIAL_BYTES:
        ret = ssl3_get_initial_bytes(s);
        if (ret <= 0) {
          goto end;
        }
        /* ssl3_get_initial_bytes sets s->state to one of
         * SSL3_ST_SR_V2_CLIENT_HELLO or SSL3_ST_SR_CLNT_HELLO_A on success. */
        break;

      case SSL3_ST_SR_V2_CLIENT_HELLO:
        ret = ssl3_get_v2_client_hello(s);
        if (ret <= 0) {
          goto end;
        }
        s->state = SSL3_ST_SR_CLNT_HELLO_A;
        break;

      case SSL3_ST_SR_CLNT_HELLO_A:
      case SSL3_ST_SR_CLNT_HELLO_B:
      case SSL3_ST_SR_CLNT_HELLO_C:
      case SSL3_ST_SR_CLNT_HELLO_D:
        s->shutdown = 0;
        ret = ssl3_get_client_hello(s);
        if (ret <= 0) {
          goto end;
        }
        s->state = SSL3_ST_SW_SRVR_HELLO_A;
        s->init_num = 0;
        break;

      case SSL3_ST_SW_SRVR_HELLO_A:
      case SSL3_ST_SW_SRVR_HELLO_B:
        ret = ssl3_send_server_hello(s);
        if (ret <= 0) {
          goto end;
        }
        if (s->hit) {
          if (s->tlsext_ticket_expected) {
            s->state = SSL3_ST_SW_SESSION_TICKET_A;
          } else {
            s->state = SSL3_ST_SW_CHANGE_A;
          }
        } else {
          s->state = SSL3_ST_SW_CERT_A;
        }
        s->init_num = 0;
        break;

      case SSL3_ST_SW_CERT_A:
      case SSL3_ST_SW_CERT_B:
        if (ssl_cipher_has_server_public_key(s->s3->tmp.new_cipher)) {
          ret = ssl3_send_server_certificate(s);
          if (ret <= 0) {
            goto end;
          }
          if (s->s3->tmp.certificate_status_expected) {
            s->state = SSL3_ST_SW_CERT_STATUS_A;
          } else {
            s->state = SSL3_ST_SW_KEY_EXCH_A;
          }
        } else {
          skip = 1;
          s->state = SSL3_ST_SW_KEY_EXCH_A;
        }
        s->init_num = 0;
        break;

      case SSL3_ST_SW_KEY_EXCH_A:
      case SSL3_ST_SW_KEY_EXCH_B:
        alg_a = s->s3->tmp.new_cipher->algorithm_auth;

        /* Send a ServerKeyExchange message if:
         * - The key exchange is ephemeral or anonymous
         *   Diffie-Hellman.
         * - There is a PSK identity hint.
         *
         * TODO(davidben): This logic is currently duplicated in d1_srvr.c. Fix
         * this. In the meantime, keep them in sync. */
        if (ssl_cipher_requires_server_key_exchange(s->s3->tmp.new_cipher) ||
            ((alg_a & SSL_aPSK) && s->psk_identity_hint)) {
          ret = ssl3_send_server_key_exchange(s);
          if (ret <= 0) {
            goto end;
          }
        } else {
          skip = 1;
        }

        s->state = SSL3_ST_SW_CERT_REQ_A;
        s->init_num = 0;
        break;

      case SSL3_ST_SW_CERT_REQ_A:
      case SSL3_ST_SW_CERT_REQ_B:
        if (s->s3->tmp.cert_request) {
          ret = ssl3_send_certificate_request(s);
          if (ret <= 0) {
            goto end;
          }
        } else {
          skip = 1;
        }
        s->state = SSL3_ST_SW_SRVR_DONE_A;
        s->init_num = 0;
        break;

      case SSL3_ST_SW_SRVR_DONE_A:
      case SSL3_ST_SW_SRVR_DONE_B:
        ret = ssl3_send_server_done(s);
        if (ret <= 0) {
          goto end;
        }
        s->s3->tmp.next_state = SSL3_ST_SR_CERT_A;
        s->state = SSL3_ST_SW_FLUSH;
        s->init_num = 0;
        break;

      case SSL3_ST_SW_FLUSH:
        /* This code originally checked to see if any data was pending using
         * BIO_CTRL_INFO and then flushed. This caused problems as documented
         * in PR#1939. The proposed fix doesn't completely resolve this issue
         * as buggy implementations of BIO_CTRL_PENDING still exist. So instead
         * we just flush unconditionally. */
        s->rwstate = SSL_WRITING;
        if (BIO_flush(s->wbio) <= 0) {
          ret = -1;
          goto end;
        }
        s->rwstate = SSL_NOTHING;

        s->state = s->s3->tmp.next_state;
        break;

      case SSL3_ST_SR_CERT_A:
      case SSL3_ST_SR_CERT_B:
        if (s->s3->tmp.cert_request) {
          ret = ssl3_get_client_certificate(s);
          if (ret <= 0) {
            goto end;
          }
        }
        s->init_num = 0;
        s->state = SSL3_ST_SR_KEY_EXCH_A;
        break;

      case SSL3_ST_SR_KEY_EXCH_A:
      case SSL3_ST_SR_KEY_EXCH_B:
        ret = ssl3_get_client_key_exchange(s);
        if (ret <= 0) {
          goto end;
        }
        s->state = SSL3_ST_SR_CERT_VRFY_A;
        s->init_num = 0;
        break;

      case SSL3_ST_SR_CERT_VRFY_A:
      case SSL3_ST_SR_CERT_VRFY_B:
        ret = ssl3_get_cert_verify(s);
        if (ret <= 0) {
          goto end;
        }

        s->state = SSL3_ST_SR_CHANGE;
        s->init_num = 0;
        break;

      case SSL3_ST_SR_CHANGE: {
        char next_proto_neg = 0;
        char channel_id = 0;
        next_proto_neg = s->s3->next_proto_neg_seen;
        channel_id = s->s3->tlsext_channel_id_valid;

        /* At this point, the next message must be entirely behind a
         * ChangeCipherSpec. */
        if (!ssl3_expect_change_cipher_spec(s)) {
          ret = -1;
          goto end;
        }
        if (next_proto_neg) {
          s->state = SSL3_ST_SR_NEXT_PROTO_A;
        } else if (channel_id) {
          s->state = SSL3_ST_SR_CHANNEL_ID_A;
        } else {
          s->state = SSL3_ST_SR_FINISHED_A;
        }
        break;
      }

      case SSL3_ST_SR_NEXT_PROTO_A:
      case SSL3_ST_SR_NEXT_PROTO_B:
        ret = ssl3_get_next_proto(s);
        if (ret <= 0) {
          goto end;
        }
        s->init_num = 0;
        if (s->s3->tlsext_channel_id_valid) {
          s->state = SSL3_ST_SR_CHANNEL_ID_A;
        } else {
          s->state = SSL3_ST_SR_FINISHED_A;
        }
        break;

      case SSL3_ST_SR_CHANNEL_ID_A:
      case SSL3_ST_SR_CHANNEL_ID_B:
        ret = ssl3_get_channel_id(s);
        if (ret <= 0) {
          goto end;
        }
        s->init_num = 0;
        s->state = SSL3_ST_SR_FINISHED_A;
        break;

      case SSL3_ST_SR_FINISHED_A:
      case SSL3_ST_SR_FINISHED_B:
        ret =
            ssl3_get_finished(s, SSL3_ST_SR_FINISHED_A, SSL3_ST_SR_FINISHED_B);
        if (ret <= 0) {
          goto end;
        }

        if (s->hit) {
          s->state = SSL_ST_OK;
        } else if (s->tlsext_ticket_expected) {
          s->state = SSL3_ST_SW_SESSION_TICKET_A;
        } else {
          s->state = SSL3_ST_SW_CHANGE_A;
        }
        /* If this is a full handshake with ChannelID then record the hashshake
         * hashes in |s->session| in case we need them to verify a ChannelID
         * signature on a resumption of this session in the future. */
        if (!s->hit && s->s3->tlsext_channel_id_new) {
          ret = tls1_record_handshake_hashes_for_channel_id(s);
          if (ret <= 0) {
            goto end;
          }
        }
        s->init_num = 0;
        break;

      case SSL3_ST_SW_SESSION_TICKET_A:
      case SSL3_ST_SW_SESSION_TICKET_B:
        ret = ssl3_send_new_session_ticket(s);
        if (ret <= 0) {
          goto end;
        }
        s->state = SSL3_ST_SW_CHANGE_A;
        s->init_num = 0;
        break;

      case SSL3_ST_SW_CHANGE_A:
      case SSL3_ST_SW_CHANGE_B:
        s->session->cipher = s->s3->tmp.new_cipher;
        if (!s->enc_method->setup_key_block(s)) {
          ret = -1;
          goto end;
        }

        ret = ssl3_send_change_cipher_spec(s, SSL3_ST_SW_CHANGE_A,
                                           SSL3_ST_SW_CHANGE_B);
        if (ret <= 0) {
          goto end;
        }
        s->state = SSL3_ST_SW_FINISHED_A;
        s->init_num = 0;

        if (!s->enc_method->change_cipher_state(
                s, SSL3_CHANGE_CIPHER_SERVER_WRITE)) {
          ret = -1;
          goto end;
        }
        break;

      case SSL3_ST_SW_FINISHED_A:
      case SSL3_ST_SW_FINISHED_B:
        ret =
            ssl3_send_finished(s, SSL3_ST_SW_FINISHED_A, SSL3_ST_SW_FINISHED_B,
                               s->enc_method->server_finished_label,
                               s->enc_method->server_finished_label_len);
        if (ret <= 0) {
          goto end;
        }
        s->state = SSL3_ST_SW_FLUSH;
        if (s->hit) {
          s->s3->tmp.next_state = SSL3_ST_SR_CHANGE;
        } else {
          s->s3->tmp.next_state = SSL_ST_OK;
        }
        s->init_num = 0;
        break;

      case SSL_ST_OK:
        /* clean a few things up */
        ssl3_cleanup_key_block(s);

        BUF_MEM_free(s->init_buf);
        s->init_buf = NULL;

        /* remove buffering on output */
        ssl_free_wbio_buffer(s);

        s->init_num = 0;

        /* If we aren't retaining peer certificates then we can discard it
         * now. */
        if (s->ctx->retain_only_sha256_of_client_certs) {
          X509_free(s->session->peer);
          s->session->peer = NULL;
        }

        s->s3->initial_handshake_complete = 1;

        ssl_update_cache(s, SSL_SESS_CACHE_SERVER);

        if (cb != NULL) {
          cb(s, SSL_CB_HANDSHAKE_DONE, 1);
        }

        ret = 1;
        goto end;

      default:
        OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_STATE);
        ret = -1;
        goto end;
    }

    if (!s->s3->tmp.reuse_message && !skip && cb != NULL && s->state != state) {
      new_state = s->state;
      s->state = state;
      cb(s, SSL_CB_ACCEPT_LOOP, 1);
      s->state = new_state;
    }
    skip = 0;
  }

end:
  s->in_handshake--;
  BUF_MEM_free(buf);
  if (cb != NULL) {
    cb(s, SSL_CB_ACCEPT_EXIT, ret);
  }
  return ret;
}

static int ssl3_read_sniff_buffer(SSL *s, size_t n) {
  if (s->s3->sniff_buffer == NULL) {
    s->s3->sniff_buffer = BUF_MEM_new();
  }
  if (s->s3->sniff_buffer == NULL || !BUF_MEM_grow(s->s3->sniff_buffer, n)) {
    return -1;
  }

  while (s->s3->sniff_buffer_len < n) {
    int ret;

    s->rwstate = SSL_READING;
    ret = BIO_read(s->rbio, s->s3->sniff_buffer->data + s->s3->sniff_buffer_len,
                   n - s->s3->sniff_buffer_len);
    if (ret <= 0) {
      return ret;
    }
    s->rwstate = SSL_NOTHING;
    s->s3->sniff_buffer_len += ret;
  }

  return 1;
}

int ssl3_get_initial_bytes(SSL *s) {
  int ret;
  const uint8_t *p;

  /* Read the first 8 bytes. To recognize a ClientHello or V2ClientHello only
   * needs the first 6 bytes, but 8 is needed to recognize CONNECT below. */
  ret = ssl3_read_sniff_buffer(s, INITIAL_SNIFF_BUFFER_SIZE);
  if (ret <= 0) {
    return ret;
  }
  assert(s->s3->sniff_buffer_len >= INITIAL_SNIFF_BUFFER_SIZE);
  p = (const uint8_t *)s->s3->sniff_buffer->data;

  /* Some dedicated error codes for protocol mixups should the application wish
   * to interpret them differently. (These do not overlap with ClientHello or
   * V2ClientHello.) */
  if (strncmp("GET ", (const char *)p, 4) == 0 ||
      strncmp("POST ", (const char *)p, 5) == 0 ||
      strncmp("HEAD ", (const char *)p, 5) == 0 ||
      strncmp("PUT ", (const char *)p, 4) == 0) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_HTTP_REQUEST);
    return -1;
  }
  if (strncmp("CONNECT ", (const char *)p, 8) == 0) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_HTTPS_PROXY_REQUEST);
    return -1;
  }

  /* Determine if this is a ClientHello or V2ClientHello. */
  if ((p[0] & 0x80) && p[2] == SSL2_MT_CLIENT_HELLO &&
      p[3] >= SSL3_VERSION_MAJOR) {
    /* This is a V2ClientHello. */
    s->state = SSL3_ST_SR_V2_CLIENT_HELLO;
    return 1;
  }
  if (p[0] == SSL3_RT_HANDSHAKE && p[1] >= SSL3_VERSION_MAJOR &&
      p[5] == SSL3_MT_CLIENT_HELLO) {
    /* This is a ClientHello. Initialize the record layer with the already
     * consumed data and continue the handshake. */
    if (!ssl3_setup_read_buffer(s)) {
      return -1;
    }
    assert(s->rstate == SSL_ST_READ_HEADER);
    /* There cannot have already been data in the record layer. */
    assert(s->s3->rbuf.left == 0);
    memcpy(s->s3->rbuf.buf, p, s->s3->sniff_buffer_len);
    s->s3->rbuf.offset = 0;
    s->s3->rbuf.left = s->s3->sniff_buffer_len;
    s->packet_length = 0;

    BUF_MEM_free(s->s3->sniff_buffer);
    s->s3->sniff_buffer = NULL;
    s->s3->sniff_buffer_len = 0;

    s->state = SSL3_ST_SR_CLNT_HELLO_A;
    return 1;
  }

  OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_PROTOCOL);
  return -1;
}

int ssl3_get_v2_client_hello(SSL *s) {
  const uint8_t *p;
  int ret;
  CBS v2_client_hello, cipher_specs, session_id, challenge;
  size_t msg_length, rand_len, len;
  uint8_t msg_type;
  uint16_t version, cipher_spec_length, session_id_length, challenge_length;
  CBB client_hello, hello_body, cipher_suites;
  uint8_t random[SSL3_RANDOM_SIZE];

  /* Read the remainder of the V2ClientHello. We have previously read 8 bytes
   * in ssl3_get_initial_bytes. */
  assert(s->s3->sniff_buffer_len >= INITIAL_SNIFF_BUFFER_SIZE);
  p = (const uint8_t *)s->s3->sniff_buffer->data;
  msg_length = ((p[0] & 0x7f) << 8) | p[1];
  if (msg_length > (1024 * 4)) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_RECORD_TOO_LARGE);
    return -1;
  }
  if (msg_length < INITIAL_SNIFF_BUFFER_SIZE - 2) {
    /* Reject lengths that are too short early. We have already read 8 bytes,
     * so we should not attempt to process an (invalid) V2ClientHello which
     * would be shorter than that. */
    OPENSSL_PUT_ERROR(SSL, SSL_R_RECORD_LENGTH_MISMATCH);
    return -1;
  }

  ret = ssl3_read_sniff_buffer(s, msg_length + 2);
  if (ret <= 0) {
    return ret;
  }
  assert(s->s3->sniff_buffer_len == msg_length + 2);
  CBS_init(&v2_client_hello, (const uint8_t *)s->s3->sniff_buffer->data + 2,
           msg_length);

  /* The V2ClientHello without the length is incorporated into the Finished
   * hash. */
  if (!ssl3_finish_mac(s, CBS_data(&v2_client_hello),
                       CBS_len(&v2_client_hello))) {
    return -1;
  }
  if (s->msg_callback) {
    s->msg_callback(0, SSL2_VERSION, 0, CBS_data(&v2_client_hello),
                    CBS_len(&v2_client_hello), s, s->msg_callback_arg);
  }

  if (!CBS_get_u8(&v2_client_hello, &msg_type) ||
      !CBS_get_u16(&v2_client_hello, &version) ||
      !CBS_get_u16(&v2_client_hello, &cipher_spec_length) ||
      !CBS_get_u16(&v2_client_hello, &session_id_length) ||
      !CBS_get_u16(&v2_client_hello, &challenge_length) ||
      !CBS_get_bytes(&v2_client_hello, &cipher_specs, cipher_spec_length) ||
      !CBS_get_bytes(&v2_client_hello, &session_id, session_id_length) ||
      !CBS_get_bytes(&v2_client_hello, &challenge, challenge_length) ||
      CBS_len(&v2_client_hello) != 0) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
    return -1;
  }

  /* msg_type has already been checked. */
  assert(msg_type == SSL2_MT_CLIENT_HELLO);

  /* The client_random is the V2ClientHello challenge. Truncate or
   * left-pad with zeros as needed. */
  memset(random, 0, SSL3_RANDOM_SIZE);
  rand_len = CBS_len(&challenge);
  if (rand_len > SSL3_RANDOM_SIZE) {
    rand_len = SSL3_RANDOM_SIZE;
  }
  memcpy(random + (SSL3_RANDOM_SIZE - rand_len), CBS_data(&challenge),
         rand_len);

  /* Write out an equivalent SSLv3 ClientHello. */
  CBB_zero(&client_hello);
  if (!CBB_init_fixed(&client_hello, (uint8_t *)s->init_buf->data,
                      s->init_buf->max) ||
      !CBB_add_u8(&client_hello, SSL3_MT_CLIENT_HELLO) ||
      !CBB_add_u24_length_prefixed(&client_hello, &hello_body) ||
      !CBB_add_u16(&hello_body, version) ||
      !CBB_add_bytes(&hello_body, random, SSL3_RANDOM_SIZE) ||
      /* No session id. */
      !CBB_add_u8(&hello_body, 0) ||
      !CBB_add_u16_length_prefixed(&hello_body, &cipher_suites)) {
    CBB_cleanup(&client_hello);
    OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
    return -1;
  }

  /* Copy the cipher suites. */
  while (CBS_len(&cipher_specs) > 0) {
    uint32_t cipher_spec;
    if (!CBS_get_u24(&cipher_specs, &cipher_spec)) {
      CBB_cleanup(&client_hello);
      OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
      return -1;
    }

    /* Skip SSLv2 ciphers. */
    if ((cipher_spec & 0xff0000) != 0) {
      continue;
    }
    if (!CBB_add_u16(&cipher_suites, cipher_spec)) {
      CBB_cleanup(&client_hello);
      OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
      return -1;
    }
  }

  /* Add the null compression scheme and finish. */
  if (!CBB_add_u8(&hello_body, 1) || !CBB_add_u8(&hello_body, 0) ||
      !CBB_finish(&client_hello, NULL, &len)) {
    CBB_cleanup(&client_hello);
    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
    return -1;
  }

  /* Mark the message for "re"-use by the version-specific method. */
  s->s3->tmp.reuse_message = 1;
  s->s3->tmp.message_type = SSL3_MT_CLIENT_HELLO;
  /* The handshake message header is 4 bytes. */
  s->s3->tmp.message_size = len - 4;

  /* Drop the sniff buffer. */
  BUF_MEM_free(s->s3->sniff_buffer);
  s->s3->sniff_buffer = NULL;
  s->s3->sniff_buffer_len = 0;

  return 1;
}

int ssl3_get_client_hello(SSL *s) {
  int ok, al = SSL_AD_INTERNAL_ERROR, ret = -1;
  long n;
  const SSL_CIPHER *c;
  STACK_OF(SSL_CIPHER) *ciphers = NULL;
  struct ssl_early_callback_ctx early_ctx;
  CBS client_hello;
  uint16_t client_version;
  CBS client_random, session_id, cipher_suites, compression_methods;
  SSL_SESSION *session = NULL;

  /* We do this so that we will respond with our native type. If we are TLSv1
   * and we get SSLv3, we will respond with TLSv1, This down switching should
   * be handled by a different method. If we are SSLv3, we will respond with
   * SSLv3, even if prompted with TLSv1. */
  switch (s->state) {
    case SSL3_ST_SR_CLNT_HELLO_A:
    case SSL3_ST_SR_CLNT_HELLO_B:
      n = s->method->ssl_get_message(
          s, SSL3_ST_SR_CLNT_HELLO_A, SSL3_ST_SR_CLNT_HELLO_B,
          SSL3_MT_CLIENT_HELLO, SSL3_RT_MAX_PLAIN_LENGTH,
          ssl_hash_message, &ok);

      if (!ok) {
        return n;
      }

      s->state = SSL3_ST_SR_CLNT_HELLO_C;
      /* fallthrough */
    case SSL3_ST_SR_CLNT_HELLO_C:
    case SSL3_ST_SR_CLNT_HELLO_D:
      /* We have previously parsed the ClientHello message, and can't call
       * ssl_get_message again without hashing the message into the Finished
       * digest again. */
      n = s->init_num;

      memset(&early_ctx, 0, sizeof(early_ctx));
      early_ctx.ssl = s;
      early_ctx.client_hello = s->init_msg;
      early_ctx.client_hello_len = n;
      if (!ssl_early_callback_init(&early_ctx)) {
        al = SSL_AD_DECODE_ERROR;
        OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_PARSE_FAILED);
        goto f_err;
      }

      if (s->state == SSL3_ST_SR_CLNT_HELLO_C &&
          s->ctx->select_certificate_cb != NULL) {
        s->state = SSL3_ST_SR_CLNT_HELLO_D;
        switch (s->ctx->select_certificate_cb(&early_ctx)) {
          case 0:
            s->rwstate = SSL_CERTIFICATE_SELECTION_PENDING;
            goto err;

          case -1:
            /* Connection rejected. */
            al = SSL_AD_ACCESS_DENIED;
            OPENSSL_PUT_ERROR(SSL, SSL_R_CONNECTION_REJECTED);
            goto f_err;

          default:
            /* fallthrough */;
        }
      }
      s->state = SSL3_ST_SR_CLNT_HELLO_D;
      break;

    default:
      OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_STATE);
      return -1;
  }

  CBS_init(&client_hello, s->init_msg, n);
  if (!CBS_get_u16(&client_hello, &client_version) ||
      !CBS_get_bytes(&client_hello, &client_random, SSL3_RANDOM_SIZE) ||
      !CBS_get_u8_length_prefixed(&client_hello, &session_id) ||
      CBS_len(&session_id) > SSL_MAX_SSL_SESSION_ID_LENGTH) {
    al = SSL_AD_DECODE_ERROR;
    OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
    goto f_err;
  }

  /* use version from inside client hello, not from record header (may differ:
   * see RFC 2246, Appendix E, second paragraph) */
  s->client_version = client_version;

  /* Load the client random. */
  memcpy(s->s3->client_random, CBS_data(&client_random), SSL3_RANDOM_SIZE);

  if (SSL_IS_DTLS(s)) {
    CBS cookie;

    if (!CBS_get_u8_length_prefixed(&client_hello, &cookie) ||
        CBS_len(&cookie) > DTLS1_COOKIE_LENGTH) {
      al = SSL_AD_DECODE_ERROR;
      OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
      goto f_err;
    }
  }

  /* Note: This codepath may run twice if |ssl_get_prev_session| completes
   * asynchronously.
   *
   * TODO(davidben): Clean up the order of events around ClientHello
   * processing. */
  if (!s->s3->have_version) {
    /* Select version to use */
    uint16_t version = ssl3_get_mutual_version(s, client_version);
    if (version == 0) {
      OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_PROTOCOL);
      s->version = s->client_version;
      al = SSL_AD_PROTOCOL_VERSION;
      goto f_err;
    }
    s->version = version;
    s->enc_method = ssl3_get_enc_method(version);
    assert(s->enc_method != NULL);
    /* At this point, the connection's version is known and |s->version| is
     * fixed. Begin enforcing the record-layer version. */
    s->s3->have_version = 1;
  } else if (SSL_IS_DTLS(s) ? (s->client_version > s->version)
                            : (s->client_version < s->version)) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_VERSION_NUMBER);
    al = SSL_AD_PROTOCOL_VERSION;
    goto f_err;
  }

  s->hit = 0;
  int send_new_ticket = 0;
  switch (ssl_get_prev_session(s, &session, &send_new_ticket, &early_ctx)) {
    case ssl_session_success:
      break;
    case ssl_session_error:
      goto err;
    case ssl_session_retry:
      s->rwstate = SSL_PENDING_SESSION;
      goto err;
  }
  s->tlsext_ticket_expected = send_new_ticket;

  /* The EMS state is needed when making the resumption decision, but
   * extensions are not normally parsed until later. This detects the EMS
   * extension for the resumption decision and it's checked against the result
   * of the normal parse later in this function. */
  const uint8_t *ems_data;
  size_t ems_len;
  int have_extended_master_secret =
      s->version != SSL3_VERSION &&
      SSL_early_callback_ctx_extension_get(&early_ctx,
                                           TLSEXT_TYPE_extended_master_secret,
                                           &ems_data, &ems_len) &&
      ems_len == 0;

  if (session != NULL) {
    if (session->extended_master_secret &&
        !have_extended_master_secret) {
      /* A ClientHello without EMS that attempts to resume a session with EMS
       * is fatal to the connection. */
      al = SSL_AD_HANDSHAKE_FAILURE;
      OPENSSL_PUT_ERROR(SSL, SSL_R_RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION);
      goto f_err;
    }

    s->hit =
        /* Only resume if the session's version matches the negotiated version:
         * most clients do not accept a mismatch. */
        s->version == session->ssl_version &&
        /* If the client offers the EMS extension, but the previous session
         * didn't use it, then negotiate a new session. */
        have_extended_master_secret == session->extended_master_secret;
  }

  if (s->hit) {
    /* Use the new session. */
    SSL_SESSION_free(s->session);
    s->session = session;
    session = NULL;

    s->verify_result = s->session->verify_result;
  } else if (!ssl_get_new_session(s, 1)) {
    goto err;
  }

  if (s->ctx->dos_protection_cb != NULL && s->ctx->dos_protection_cb(&early_ctx) == 0) {
    /* Connection rejected for DOS reasons. */
    al = SSL_AD_ACCESS_DENIED;
    OPENSSL_PUT_ERROR(SSL, SSL_R_CONNECTION_REJECTED);
    goto f_err;
  }

  if (!CBS_get_u16_length_prefixed(&client_hello, &cipher_suites) ||
      CBS_len(&cipher_suites) == 0 ||
      CBS_len(&cipher_suites) % 2 != 0 ||
      !CBS_get_u8_length_prefixed(&client_hello, &compression_methods) ||
      CBS_len(&compression_methods) == 0) {
    al = SSL_AD_DECODE_ERROR;
    OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
    goto f_err;
  }

  ciphers = ssl_bytes_to_cipher_list(s, &cipher_suites);
  if (ciphers == NULL) {
    goto err;
  }

  /* If it is a hit, check that the cipher is in the list. */
  if (s->hit) {
    size_t j;
    int found_cipher = 0;
    uint32_t id = s->session->cipher->id;

    for (j = 0; j < sk_SSL_CIPHER_num(ciphers); j++) {
      c = sk_SSL_CIPHER_value(ciphers, j);
      if (c->id == id) {
        found_cipher = 1;
        break;
      }
    }

    if (!found_cipher) {
      /* we need to have the cipher in the cipher list if we are asked to reuse
       * it */
      al = SSL_AD_ILLEGAL_PARAMETER;
      OPENSSL_PUT_ERROR(SSL, SSL_R_REQUIRED_CIPHER_MISSING);
      goto f_err;
    }
  }

  /* Only null compression is supported. */
  if (memchr(CBS_data(&compression_methods), 0,
             CBS_len(&compression_methods)) == NULL) {
    al = SSL_AD_ILLEGAL_PARAMETER;
    OPENSSL_PUT_ERROR(SSL, SSL_R_NO_COMPRESSION_SPECIFIED);
    goto f_err;
  }

  /* TLS extensions. */
  if (s->version >= SSL3_VERSION &&
      !ssl_parse_clienthello_tlsext(s, &client_hello)) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_PARSE_TLSEXT);
    goto err;
  }

  /* There should be nothing left over in the record. */
  if (CBS_len(&client_hello) != 0) {
    /* wrong packet length */
    al = SSL_AD_DECODE_ERROR;
    OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_PACKET_LENGTH);
    goto f_err;
  }

  if (have_extended_master_secret != s->s3->tmp.extended_master_secret) {
    al = SSL_AD_INTERNAL_ERROR;
    OPENSSL_PUT_ERROR(SSL, SSL_R_EMS_STATE_INCONSISTENT);
    goto f_err;
  }

  /* Given ciphers and SSL_get_ciphers, we must pick a cipher */
  if (!s->hit) {
    if (ciphers == NULL) {
      al = SSL_AD_ILLEGAL_PARAMETER;
      OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CIPHERS_PASSED);
      goto f_err;
    }

    /* Let cert callback update server certificates if required */
    if (s->cert->cert_cb) {
      int rv = s->cert->cert_cb(s, s->cert->cert_cb_arg);
      if (rv == 0) {
        al = SSL_AD_INTERNAL_ERROR;
        OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_CB_ERROR);
        goto f_err;
      }
      if (rv < 0) {
        s->rwstate = SSL_X509_LOOKUP;
        goto err;
      }
      s->rwstate = SSL_NOTHING;
    }
    c = ssl3_choose_cipher(s, ciphers, ssl_get_cipher_preferences(s));

    if (c == NULL) {
      al = SSL_AD_HANDSHAKE_FAILURE;
      OPENSSL_PUT_ERROR(SSL, SSL_R_NO_SHARED_CIPHER);
      goto f_err;
    }
    s->s3->tmp.new_cipher = c;

    /* Determine whether to request a client certificate. */
    s->s3->tmp.cert_request = !!(s->verify_mode & SSL_VERIFY_PEER);
    /* Only request a certificate if Channel ID isn't negotiated. */
    if ((s->verify_mode & SSL_VERIFY_PEER_IF_NO_OBC) &&
        s->s3->tlsext_channel_id_valid) {
      s->s3->tmp.cert_request = 0;
    }
    /* Plain PSK forbids Certificate and CertificateRequest. */
    if (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK) {
      s->s3->tmp.cert_request = 0;
    }
  } else {
    /* Session-id reuse */
    s->s3->tmp.new_cipher = s->session->cipher;
    s->s3->tmp.cert_request = 0;
  }

  /* In TLS 1.2, client authentication requires hashing the handshake transcript
   * under a different hash. Otherwise, release the handshake buffer. */
  if ((!SSL_USE_SIGALGS(s) || !s->s3->tmp.cert_request) &&
      !ssl3_digest_cached_records(s, free_handshake_buffer)) {
    goto f_err;
  }

  /* we now have the following setup;
   * client_random
   * cipher_list        - our prefered list of ciphers
   * ciphers            - the clients prefered list of ciphers
   * compression        - basically ignored right now
   * ssl version is set - sslv3
   * s->session         - The ssl session has been setup.
   * s->hit             - session reuse flag
   * s->tmp.new_cipher  - the new cipher to use. */

  if (ret < 0) {
    ret = -ret;
  }

  if (0) {
  f_err:
    ssl3_send_alert(s, SSL3_AL_FATAL, al);
  }

err:
  sk_SSL_CIPHER_free(ciphers);
  SSL_SESSION_free(session);
  return ret;
}

int ssl3_send_server_hello(SSL *s) {
  uint8_t *buf;
  uint8_t *p, *d;
  int sl;
  unsigned long l;

  if (s->state == SSL3_ST_SW_SRVR_HELLO_A) {
    /* We only accept ChannelIDs on connections with ECDHE in order to avoid a
     * known attack while we fix ChannelID itself. */
    if (s->s3->tlsext_channel_id_valid &&
        (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kECDHE) == 0) {
      s->s3->tlsext_channel_id_valid = 0;
    }

    /* If this is a resumption and the original handshake didn't support
     * ChannelID then we didn't record the original handshake hashes in the
     * session and so cannot resume with ChannelIDs. */
    if (s->hit && s->s3->tlsext_channel_id_new &&
        s->session->original_handshake_hash_len == 0) {
      s->s3->tlsext_channel_id_valid = 0;
    }

    buf = (uint8_t *)s->init_buf->data;
    /* Do the message type and length last */
    d = p = ssl_handshake_start(s);

    *(p++) = s->version >> 8;
    *(p++) = s->version & 0xff;

    /* Random stuff */
    if (!ssl_fill_hello_random(s->s3->server_random, SSL3_RANDOM_SIZE,
                               1 /* server */)) {
      OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
      return -1;
    }
    memcpy(p, s->s3->server_random, SSL3_RANDOM_SIZE);
    p += SSL3_RANDOM_SIZE;

    /* There are several cases for the session ID to send
     * back in the server hello:
     * - For session reuse from the session cache, we send back the old session
     *   ID.
     * - If stateless session reuse (using a session ticket) is successful, we
     *   send back the client's "session ID" (which doesn't actually identify
     *   the session).
     * - If it is a new session, we send back the new session ID.
     * - However, if we want the new session to be single-use, we send back a
     *   0-length session ID.
     * s->hit is non-zero in either case of session reuse, so the following
     * won't overwrite an ID that we're supposed to send back. */
    if (!(s->ctx->session_cache_mode & SSL_SESS_CACHE_SERVER) && !s->hit) {
      s->session->session_id_length = 0;
    }

    sl = s->session->session_id_length;
    if (sl > (int)sizeof(s->session->session_id)) {
      OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
      return -1;
    }
    *(p++) = sl;
    memcpy(p, s->session->session_id, sl);
    p += sl;

    /* put the cipher */
    s2n(ssl_cipher_get_value(s->s3->tmp.new_cipher), p);

    /* put the compression method */
    *(p++) = 0;
    if (ssl_prepare_serverhello_tlsext(s) <= 0) {
      OPENSSL_PUT_ERROR(SSL, SSL_R_SERVERHELLO_TLSEXT);
      return -1;
    }
    p = ssl_add_serverhello_tlsext(s, p, buf + SSL3_RT_MAX_PLAIN_LENGTH);
    if (p == NULL) {
      OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
      return -1;
    }

    /* do the header */
    l = (p - d);
    if (!ssl_set_handshake_header(s, SSL3_MT_SERVER_HELLO, l)) {
      return -1;
    }
    s->state = SSL3_ST_SW_SRVR_HELLO_B;
  }

  /* SSL3_ST_SW_SRVR_HELLO_B */
  return ssl_do_write(s);
}

int ssl3_send_server_done(SSL *s) {
  if (s->state == SSL3_ST_SW_SRVR_DONE_A) {
    if (!ssl_set_handshake_header(s, SSL3_MT_SERVER_DONE, 0)) {
      return -1;
    }
    s->state = SSL3_ST_SW_SRVR_DONE_B;
  }

  /* SSL3_ST_SW_SRVR_DONE_B */
  return ssl_do_write(s);
}

int ssl3_send_server_key_exchange(SSL *s) {
  DH *dh = NULL, *dhp;
  EC_KEY *ecdh = NULL;
  uint8_t *encodedPoint = NULL;
  int encodedlen = 0;
  uint16_t curve_id = 0;
  BN_CTX *bn_ctx = NULL;
  const char *psk_identity_hint = NULL;
  size_t psk_identity_hint_len = 0;
  EVP_PKEY *pkey;
  uint8_t *p, *d;
  int al, i;
  uint32_t alg_k;
  uint32_t alg_a;
  int n;
  CERT *cert;
  BIGNUM *r[4];
  int nr[4], kn;
  BUF_MEM *buf;
  EVP_MD_CTX md_ctx;

  EVP_MD_CTX_init(&md_ctx);
  if (s->state == SSL3_ST_SW_KEY_EXCH_A) {
    alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
    alg_a = s->s3->tmp.new_cipher->algorithm_auth;
    cert = s->cert;

    buf = s->init_buf;

    r[0] = r[1] = r[2] = r[3] = NULL;
    n = 0;
    if (alg_a & SSL_aPSK) {
      /* size for PSK identity hint */
      psk_identity_hint = s->psk_identity_hint;
      if (psk_identity_hint) {
        psk_identity_hint_len = strlen(psk_identity_hint);
      } else {
        psk_identity_hint_len = 0;
      }
      n += 2 + psk_identity_hint_len;
    }

    if (alg_k & SSL_kDHE) {
      dhp = cert->dh_tmp;
      if (dhp == NULL && s->cert->dh_tmp_cb != NULL) {
        dhp = s->cert->dh_tmp_cb(s, 0, 1024);
      }
      if (dhp == NULL) {
        al = SSL_AD_HANDSHAKE_FAILURE;
        OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_TMP_DH_KEY);
        goto f_err;
      }

      if (s->s3->tmp.dh != NULL) {
        OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
        goto err;
      }
      dh = DHparams_dup(dhp);
      if (dh == NULL) {
        OPENSSL_PUT_ERROR(SSL, ERR_R_DH_LIB);
        goto err;
      }
      s->s3->tmp.dh = dh;

      if (!DH_generate_key(dh)) {
        OPENSSL_PUT_ERROR(SSL, ERR_R_DH_LIB);
        goto err;
      }

      r[0] = dh->p;
      r[1] = dh->g;
      r[2] = dh->pub_key;
    } else if (alg_k & SSL_kECDHE) {
      /* Determine the curve to use. */
      int nid = NID_undef;
      if (cert->ecdh_nid != NID_undef) {
        nid = cert->ecdh_nid;
      } else if (cert->ecdh_tmp_cb != NULL) {
        /* Note: |ecdh_tmp_cb| does NOT pass ownership of the result
         * to the caller. */
        EC_KEY *template = s->cert->ecdh_tmp_cb(s, 0, 1024);
        if (template != NULL && EC_KEY_get0_group(template) != NULL) {
          nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(template));
        }
      } else {
        nid = tls1_get_shared_curve(s);
      }
      if (nid == NID_undef) {
        al = SSL_AD_HANDSHAKE_FAILURE;
        OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_TMP_ECDH_KEY);
        goto f_err;
      }

      if (s->s3->tmp.ecdh != NULL) {
        OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
        goto err;
      }
      ecdh = EC_KEY_new_by_curve_name(nid);
      if (ecdh == NULL) {
        goto err;
      }
      s->s3->tmp.ecdh = ecdh;

      if (!EC_KEY_generate_key(ecdh)) {
        OPENSSL_PUT_ERROR(SSL, ERR_R_ECDH_LIB);
        goto err;
      }

      /* We only support ephemeral ECDH keys over named (not generic) curves. */
      const EC_GROUP *group = EC_KEY_get0_group(ecdh);
      if (!tls1_ec_nid2curve_id(&curve_id, EC_GROUP_get_curve_name(group))) {
        OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_ELLIPTIC_CURVE);
        goto err;
      }

      /* Encode the public key. First check the size of encoding and allocate
       * memory accordingly. */
      encodedlen =
          EC_POINT_point2oct(group, EC_KEY_get0_public_key(ecdh),
                             POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL);

      encodedPoint = (uint8_t *)OPENSSL_malloc(encodedlen * sizeof(uint8_t));
      bn_ctx = BN_CTX_new();
      if (encodedPoint == NULL || bn_ctx == NULL) {
        OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
        goto err;
      }

      encodedlen = EC_POINT_point2oct(group, EC_KEY_get0_public_key(ecdh),
                                      POINT_CONVERSION_UNCOMPRESSED,
                                      encodedPoint, encodedlen, bn_ctx);

      if (encodedlen == 0) {
        OPENSSL_PUT_ERROR(SSL, ERR_R_ECDH_LIB);
        goto err;
      }

      BN_CTX_free(bn_ctx);
      bn_ctx = NULL;

      /* We only support named (not generic) curves in ECDH ephemeral key
       * exchanges. In this situation, we need four additional bytes to encode
       * the entire ServerECDHParams structure. */
      n += 4 + encodedlen;

      /* We'll generate the serverKeyExchange message explicitly so we can set
       * these to NULLs */
      r[0] = NULL;
      r[1] = NULL;
      r[2] = NULL;
      r[3] = NULL;
    } else if (!(alg_k & SSL_kPSK)) {
      al = SSL_AD_HANDSHAKE_FAILURE;
      OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE);
      goto f_err;
    }

    for (i = 0; i < 4 && r[i] != NULL; i++) {
      nr[i] = BN_num_bytes(r[i]);
      n += 2 + nr[i];
    }

    if (ssl_cipher_has_server_public_key(s->s3->tmp.new_cipher)) {
      pkey = s->cert->privatekey;
      if (pkey == NULL) {
        al = SSL_AD_DECODE_ERROR;
        goto f_err;
      }
      kn = EVP_PKEY_size(pkey);
    } else {
      pkey = NULL;
      kn = 0;
    }

    if (!BUF_MEM_grow_clean(buf, n + SSL_HM_HEADER_LENGTH(s) + kn)) {
      OPENSSL_PUT_ERROR(SSL, ERR_LIB_BUF);
      goto err;
    }
    d = p = ssl_handshake_start(s);

    for (i = 0; i < 4 && r[i] != NULL; i++) {
      s2n(nr[i], p);
      BN_bn2bin(r[i], p);
      p += nr[i];
    }

    /* Note: ECDHE PSK ciphersuites use SSL_kECDHE and SSL_aPSK. When one of
     * them is used, the server key exchange record needs to have both the
     * psk_identity_hint and the ServerECDHParams. */
    if (alg_a & SSL_aPSK) {
      /* copy PSK identity hint (if provided) */
      s2n(psk_identity_hint_len, p);
      if (psk_identity_hint_len > 0) {
        memcpy(p, psk_identity_hint, psk_identity_hint_len);
        p += psk_identity_hint_len;
      }
    }

    if (alg_k & SSL_kECDHE) {
      /* We only support named (not generic) curves. In this situation, the
       * serverKeyExchange message has:
       * [1 byte CurveType], [2 byte CurveName]
       * [1 byte length of encoded point], followed by
       * the actual encoded point itself. */
      *(p++) = NAMED_CURVE_TYPE;
      *(p++) = (uint8_t)(curve_id >> 8);
      *(p++) = (uint8_t)(curve_id & 0xff);
      *(p++) = encodedlen;
      memcpy(p, encodedPoint, encodedlen);
      p += encodedlen;
      OPENSSL_free(encodedPoint);
      encodedPoint = NULL;
    }

    /* not anonymous */
    if (pkey != NULL) {
      /* n is the length of the params, they start at &(d[4]) and p points to
       * the space at the end. */
      const EVP_MD *md;
      size_t sig_len = EVP_PKEY_size(pkey);

      /* Determine signature algorithm. */
      if (SSL_USE_SIGALGS(s)) {
        md = tls1_choose_signing_digest(s);
        if (!tls12_get_sigandhash(s, p, md)) {
          /* Should never happen */
          al = SSL_AD_INTERNAL_ERROR;
          OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
          goto f_err;
        }
        p += 2;
      } else if (pkey->type == EVP_PKEY_RSA) {
        md = EVP_md5_sha1();
      } else {
        md = EVP_sha1();
      }

      if (!EVP_DigestSignInit(&md_ctx, NULL, md, NULL, pkey) ||
          !EVP_DigestSignUpdate(&md_ctx, s->s3->client_random,
                                SSL3_RANDOM_SIZE) ||
          !EVP_DigestSignUpdate(&md_ctx, s->s3->server_random,
                                SSL3_RANDOM_SIZE) ||
          !EVP_DigestSignUpdate(&md_ctx, d, n) ||
          !EVP_DigestSignFinal(&md_ctx, &p[2], &sig_len)) {
        OPENSSL_PUT_ERROR(SSL, ERR_LIB_EVP);
        goto err;
      }

      s2n(sig_len, p);
      n += sig_len + 2;
      if (SSL_USE_SIGALGS(s)) {
        n += 2;
      }
    }

    if (!ssl_set_handshake_header(s, SSL3_MT_SERVER_KEY_EXCHANGE, n)) {
      goto err;
    }
  }

  s->state = SSL3_ST_SW_KEY_EXCH_B;
  EVP_MD_CTX_cleanup(&md_ctx);
  return ssl_do_write(s);

f_err:
  ssl3_send_alert(s, SSL3_AL_FATAL, al);
err:
  OPENSSL_free(encodedPoint);
  BN_CTX_free(bn_ctx);
  EVP_MD_CTX_cleanup(&md_ctx);
  return -1;
}

int ssl3_send_certificate_request(SSL *s) {
  uint8_t *p, *d;
  size_t i;
  int j, nl, off, n;
  STACK_OF(X509_NAME) *sk = NULL;
  X509_NAME *name;
  BUF_MEM *buf;

  if (s->state == SSL3_ST_SW_CERT_REQ_A) {
    buf = s->init_buf;

    d = p = ssl_handshake_start(s);

    /* get the list of acceptable cert types */
    p++;
    n = ssl3_get_req_cert_type(s, p);
    d[0] = n;
    p += n;
    n++;

    if (SSL_USE_SIGALGS(s)) {
      const uint8_t *psigs;
      nl = tls12_get_psigalgs(s, &psigs);
      s2n(nl, p);
      memcpy(p, psigs, nl);
      p += nl;
      n += nl + 2;
    }

    off = n;
    p += 2;
    n += 2;

    sk = SSL_get_client_CA_list(s);
    nl = 0;
    if (sk != NULL) {
      for (i = 0; i < sk_X509_NAME_num(sk); i++) {
        name = sk_X509_NAME_value(sk, i);
        j = i2d_X509_NAME(name, NULL);
        if (!BUF_MEM_grow_clean(buf, SSL_HM_HEADER_LENGTH(s) + n + j + 2)) {
          OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
          goto err;
        }
        p = ssl_handshake_start(s) + n;
        s2n(j, p);
        i2d_X509_NAME(name, &p);
        n += 2 + j;
        nl += 2 + j;
      }
    }

    /* else no CA names */
    p = ssl_handshake_start(s) + off;
    s2n(nl, p);

    if (!ssl_set_handshake_header(s, SSL3_MT_CERTIFICATE_REQUEST, n)) {
      goto err;
    }
    s->state = SSL3_ST_SW_CERT_REQ_B;
  }

  /* SSL3_ST_SW_CERT_REQ_B */
  return ssl_do_write(s);

err:
  return -1;
}

int ssl3_get_client_key_exchange(SSL *s) {
  int al, ok;
  long n;
  CBS client_key_exchange;
  uint32_t alg_k;
  uint32_t alg_a;
  uint8_t *premaster_secret = NULL;
  size_t premaster_secret_len = 0;
  RSA *rsa = NULL;
  uint8_t *decrypt_buf = NULL;
  EVP_PKEY *pkey = NULL;
  BIGNUM *pub = NULL;
  DH *dh_srvr;

  EC_KEY *srvr_ecdh = NULL;
  EVP_PKEY *clnt_pub_pkey = NULL;
  EC_POINT *clnt_ecpoint = NULL;
  BN_CTX *bn_ctx = NULL;
  unsigned int psk_len = 0;
  uint8_t psk[PSK_MAX_PSK_LEN];

  n = s->method->ssl_get_message(s, SSL3_ST_SR_KEY_EXCH_A,
                                 SSL3_ST_SR_KEY_EXCH_B,
                                 SSL3_MT_CLIENT_KEY_EXCHANGE, 2048, /* ??? */
                                 ssl_hash_message, &ok);

  if (!ok) {
    return n;
  }

  CBS_init(&client_key_exchange, s->init_msg, n);

  alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
  alg_a = s->s3->tmp.new_cipher->algorithm_auth;

  /* If using a PSK key exchange, prepare the pre-shared key. */
  if (alg_a & SSL_aPSK) {
    CBS psk_identity;

    /* If using PSK, the ClientKeyExchange contains a psk_identity. If PSK,
     * then this is the only field in the message. */
    if (!CBS_get_u16_length_prefixed(&client_key_exchange, &psk_identity) ||
        ((alg_k & SSL_kPSK) && CBS_len(&client_key_exchange) != 0)) {
      OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
      al = SSL_AD_DECODE_ERROR;
      goto f_err;
    }

    if (s->psk_server_callback == NULL) {
      OPENSSL_PUT_ERROR(SSL, SSL_R_PSK_NO_SERVER_CB);
      al = SSL_AD_INTERNAL_ERROR;
      goto f_err;
    }

    if (CBS_len(&psk_identity) > PSK_MAX_IDENTITY_LEN ||
        CBS_contains_zero_byte(&psk_identity)) {
      OPENSSL_PUT_ERROR(SSL, SSL_R_DATA_LENGTH_TOO_LONG);
      al = SSL_AD_ILLEGAL_PARAMETER;
      goto f_err;
    }

    if (!CBS_strdup(&psk_identity, &s->session->psk_identity)) {
      al = SSL_AD_INTERNAL_ERROR;
      OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
      goto f_err;
    }

    /* Look up the key for the identity. */
    psk_len =
        s->psk_server_callback(s, s->session->psk_identity, psk, sizeof(psk));
    if (psk_len > PSK_MAX_PSK_LEN) {
      OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
      al = SSL_AD_INTERNAL_ERROR;
      goto f_err;
    } else if (psk_len == 0) {
      /* PSK related to the given identity not found */
      OPENSSL_PUT_ERROR(SSL, SSL_R_PSK_IDENTITY_NOT_FOUND);
      al = SSL_AD_UNKNOWN_PSK_IDENTITY;
      goto f_err;
    }
  }

  /* Depending on the key exchange method, compute |premaster_secret| and
   * |premaster_secret_len|. */
  if (alg_k & SSL_kRSA) {
    CBS encrypted_premaster_secret;
    uint8_t rand_premaster_secret[SSL_MAX_MASTER_KEY_LENGTH];
    uint8_t good;
    size_t rsa_size, decrypt_len, premaster_index, j;

    pkey = s->cert->privatekey;
    if (pkey == NULL || pkey->type != EVP_PKEY_RSA || pkey->pkey.rsa == NULL) {
      al = SSL_AD_HANDSHAKE_FAILURE;
      OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_RSA_CERTIFICATE);
      goto f_err;
    }
    rsa = pkey->pkey.rsa;

    /* TLS and [incidentally] DTLS{0xFEFF} */
    if (s->version > SSL3_VERSION) {
      CBS copy = client_key_exchange;
      if (!CBS_get_u16_length_prefixed(&client_key_exchange,
                                       &encrypted_premaster_secret) ||
          CBS_len(&client_key_exchange) != 0) {
        if (!(s->options & SSL_OP_TLS_D5_BUG)) {
          al = SSL_AD_DECODE_ERROR;
          OPENSSL_PUT_ERROR(SSL, SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG);
          goto f_err;
        } else {
          encrypted_premaster_secret = copy;
        }
      }
    } else {
      encrypted_premaster_secret = client_key_exchange;
    }

    /* Reject overly short RSA keys because we want to be sure that the buffer
     * size makes it safe to iterate over the entire size of a premaster secret
     * (SSL_MAX_MASTER_KEY_LENGTH). The actual expected size is larger due to
     * RSA padding, but the bound is sufficient to be safe. */
    rsa_size = RSA_size(rsa);
    if (rsa_size < SSL_MAX_MASTER_KEY_LENGTH) {
      al = SSL_AD_DECRYPT_ERROR;
      OPENSSL_PUT_ERROR(SSL, SSL_R_DECRYPTION_FAILED);
      goto f_err;
    }

    /* We must not leak whether a decryption failure occurs because of
     * Bleichenbacher's attack on PKCS #1 v1.5 RSA padding (see RFC 2246,
     * section 7.4.7.1). The code follows that advice of the TLS RFC and
     * generates a random premaster secret for the case that the decrypt fails.
     * See https://tools.ietf.org/html/rfc5246#section-7.4.7.1 */
    if (!RAND_bytes(rand_premaster_secret, sizeof(rand_premaster_secret))) {
      goto err;
    }

    /* Allocate a buffer large enough for an RSA decryption. */
    decrypt_buf = OPENSSL_malloc(rsa_size);
    if (decrypt_buf == NULL) {
      OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
      goto err;
    }

    /* Decrypt with no padding. PKCS#1 padding will be removed as part of the
     * timing-sensitive code below. */
    if (!RSA_decrypt(rsa, &decrypt_len, decrypt_buf, rsa_size,
                     CBS_data(&encrypted_premaster_secret),
                     CBS_len(&encrypted_premaster_secret), RSA_NO_PADDING)) {
      goto err;
    }
    if (decrypt_len != rsa_size) {
      /* This should never happen, but do a check so we do not read
       * uninitialized memory. */
      OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
      goto err;
    }

    /* Remove the PKCS#1 padding and adjust |decrypt_len| as appropriate.
     * |good| will be 0xff if the premaster is acceptable and zero otherwise.
     * */
    good =
        constant_time_eq_int_8(RSA_message_index_PKCS1_type_2(
                                   decrypt_buf, decrypt_len, &premaster_index),
                               1);
    decrypt_len = decrypt_len - premaster_index;

    /* decrypt_len should be SSL_MAX_MASTER_KEY_LENGTH. */
    good &= constant_time_eq_8(decrypt_len, SSL_MAX_MASTER_KEY_LENGTH);

    /* Copy over the unpadded premaster. Whatever the value of
     * |decrypt_good_mask|, copy as if the premaster were the right length. It
     * is important the memory access pattern be constant. */
    premaster_secret =
        BUF_memdup(decrypt_buf + (rsa_size - SSL_MAX_MASTER_KEY_LENGTH),
                   SSL_MAX_MASTER_KEY_LENGTH);
    if (premaster_secret == NULL) {
      OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
      goto err;
    }
    OPENSSL_free(decrypt_buf);
    decrypt_buf = NULL;

    /* If the version in the decrypted pre-master secret is correct then
     * version_good will be 0xff, otherwise it'll be zero. The
     * Klima-Pokorny-Rosa extension of Bleichenbacher's attack
     * (http://eprint.iacr.org/2003/052/) exploits the version number check as
     * a "bad version oracle". Thus version checks are done in constant time
     * and are treated like any other decryption error. */
    good &= constant_time_eq_8(premaster_secret[0],
                               (unsigned)(s->client_version >> 8));
    good &= constant_time_eq_8(premaster_secret[1],
                               (unsigned)(s->client_version & 0xff));

    /* Now copy rand_premaster_secret over premaster_secret using
     * decrypt_good_mask. */
    for (j = 0; j < sizeof(rand_premaster_secret); j++) {
      premaster_secret[j] = constant_time_select_8(good, premaster_secret[j],
                                                   rand_premaster_secret[j]);
    }

    premaster_secret_len = sizeof(rand_premaster_secret);
  } else if (alg_k & SSL_kDHE) {
    CBS dh_Yc;
    int dh_len;

    if (!CBS_get_u16_length_prefixed(&client_key_exchange, &dh_Yc) ||
        CBS_len(&dh_Yc) == 0 || CBS_len(&client_key_exchange) != 0) {
      OPENSSL_PUT_ERROR(SSL, SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG);
      al = SSL_R_DECODE_ERROR;
      goto f_err;
    }

    if (s->s3->tmp.dh == NULL) {
      al = SSL_AD_HANDSHAKE_FAILURE;
      OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_TMP_DH_KEY);
      goto f_err;
    }
    dh_srvr = s->s3->tmp.dh;

    pub = BN_bin2bn(CBS_data(&dh_Yc), CBS_len(&dh_Yc), NULL);
    if (pub == NULL) {
      OPENSSL_PUT_ERROR(SSL, SSL_R_BN_LIB);
      goto err;
    }

    /* Allocate a buffer for the premaster secret. */
    premaster_secret = OPENSSL_malloc(DH_size(dh_srvr));
    if (premaster_secret == NULL) {
      OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
      BN_clear_free(pub);
      goto err;
    }

    dh_len = DH_compute_key(premaster_secret, pub, dh_srvr);
    if (dh_len <= 0) {
      OPENSSL_PUT_ERROR(SSL, ERR_R_DH_LIB);
      BN_clear_free(pub);
      goto err;
    }

    DH_free(s->s3->tmp.dh);
    s->s3->tmp.dh = NULL;
    BN_clear_free(pub);
    pub = NULL;

    premaster_secret_len = dh_len;
  } else if (alg_k & SSL_kECDHE) {
    int field_size = 0, ecdh_len;
    const EC_KEY *tkey;
    const EC_GROUP *group;
    const BIGNUM *priv_key;
    CBS ecdh_Yc;

    /* initialize structures for server's ECDH key pair */
    srvr_ecdh = EC_KEY_new();
    if (srvr_ecdh == NULL) {
      OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
      goto err;
    }

    /* Use the ephermeral values we saved when generating the ServerKeyExchange
     * msg. */
    tkey = s->s3->tmp.ecdh;

    group = EC_KEY_get0_group(tkey);
    priv_key = EC_KEY_get0_private_key(tkey);

    if (!EC_KEY_set_group(srvr_ecdh, group) ||
        !EC_KEY_set_private_key(srvr_ecdh, priv_key)) {
      OPENSSL_PUT_ERROR(SSL, ERR_R_EC_LIB);
      goto err;
    }

    /* Let's get client's public key */
    clnt_ecpoint = EC_POINT_new(group);
    if (clnt_ecpoint == NULL) {
      OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
      goto err;
    }

    /* Get client's public key from encoded point in the ClientKeyExchange
     * message. */
    if (!CBS_get_u8_length_prefixed(&client_key_exchange, &ecdh_Yc) ||
        CBS_len(&client_key_exchange) != 0) {
      al = SSL_AD_DECODE_ERROR;
      OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
      goto f_err;
    }

    bn_ctx = BN_CTX_new();
    if (bn_ctx == NULL) {
      OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
      goto err;
    }

    if (!EC_POINT_oct2point(group, clnt_ecpoint, CBS_data(&ecdh_Yc),
                            CBS_len(&ecdh_Yc), bn_ctx)) {
      OPENSSL_PUT_ERROR(SSL, ERR_R_EC_LIB);
      goto err;
    }

    /* Allocate a buffer for both the secret and the PSK. */
    field_size = EC_GROUP_get_degree(group);
    if (field_size <= 0) {
      OPENSSL_PUT_ERROR(SSL, ERR_R_ECDH_LIB);
      goto err;
    }

    ecdh_len = (field_size + 7) / 8;
    premaster_secret = OPENSSL_malloc(ecdh_len);
    if (premaster_secret == NULL) {
      OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
      goto err;
    }

    /* Compute the shared pre-master secret */
    ecdh_len = ECDH_compute_key(premaster_secret, ecdh_len, clnt_ecpoint,
                                srvr_ecdh, NULL);
    if (ecdh_len <= 0) {
      OPENSSL_PUT_ERROR(SSL, ERR_R_ECDH_LIB);
      goto err;
    }

    EVP_PKEY_free(clnt_pub_pkey);
    clnt_pub_pkey = NULL;
    EC_POINT_free(clnt_ecpoint);
    clnt_ecpoint = NULL;
    EC_KEY_free(srvr_ecdh);
    srvr_ecdh = NULL;
    BN_CTX_free(bn_ctx);
    bn_ctx = NULL;
    EC_KEY_free(s->s3->tmp.ecdh);
    s->s3->tmp.ecdh = NULL;

    premaster_secret_len = ecdh_len;
  } else if (alg_k & SSL_kPSK) {
    /* For plain PSK, other_secret is a block of 0s with the same length as the
     * pre-shared key. */
    premaster_secret_len = psk_len;
    premaster_secret = OPENSSL_malloc(premaster_secret_len);
    if (premaster_secret == NULL) {
      OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
      goto err;
    }
    memset(premaster_secret, 0, premaster_secret_len);
  } else {
    al = SSL_AD_HANDSHAKE_FAILURE;
    OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CIPHER_TYPE);
    goto f_err;
  }

  /* For a PSK cipher suite, the actual pre-master secret is combined with the
   * pre-shared key. */
  if (alg_a & SSL_aPSK) {
    CBB new_premaster, child;
    uint8_t *new_data;
    size_t new_len;

    CBB_zero(&new_premaster);
    if (!CBB_init(&new_premaster, 2 + psk_len + 2 + premaster_secret_len) ||
        !CBB_add_u16_length_prefixed(&new_premaster, &child) ||
        !CBB_add_bytes(&child, premaster_secret, premaster_secret_len) ||
        !CBB_add_u16_length_prefixed(&new_premaster, &child) ||
        !CBB_add_bytes(&child, psk, psk_len) ||
        !CBB_finish(&new_premaster, &new_data, &new_len)) {
      OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
      CBB_cleanup(&new_premaster);
      goto err;
    }

    OPENSSL_cleanse(premaster_secret, premaster_secret_len);
    OPENSSL_free(premaster_secret);
    premaster_secret = new_data;
    premaster_secret_len = new_len;
  }

  /* Compute the master secret */
  s->session->master_key_length = s->enc_method->generate_master_secret(
      s, s->session->master_key, premaster_secret, premaster_secret_len);
  if (s->session->master_key_length == 0) {
    goto err;
  }
  s->session->extended_master_secret = s->s3->tmp.extended_master_secret;

  OPENSSL_cleanse(premaster_secret, premaster_secret_len);
  OPENSSL_free(premaster_secret);
  return 1;

f_err:
  ssl3_send_alert(s, SSL3_AL_FATAL, al);
err:
  if (premaster_secret) {
    if (premaster_secret_len) {
      OPENSSL_cleanse(premaster_secret, premaster_secret_len);
    }
    OPENSSL_free(premaster_secret);
  }
  OPENSSL_free(decrypt_buf);
  EVP_PKEY_free(clnt_pub_pkey);
  EC_POINT_free(clnt_ecpoint);
  EC_KEY_free(srvr_ecdh);
  BN_CTX_free(bn_ctx);

  return -1;
}

int ssl3_get_cert_verify(SSL *s) {
  int al, ok, ret = 0;
  long n;
  CBS certificate_verify, signature;
  X509 *peer = s->session->peer;
  EVP_PKEY *pkey = NULL;
  const EVP_MD *md = NULL;
  uint8_t digest[EVP_MAX_MD_SIZE];
  size_t digest_length;
  EVP_PKEY_CTX *pctx = NULL;

  /* Only RSA and ECDSA client certificates are supported, so a
   * CertificateVerify is required if and only if there's a client certificate.
   * */
  if (peer == NULL) {
    if (s->s3->handshake_buffer &&
        !ssl3_digest_cached_records(s, free_handshake_buffer)) {
      return -1;
    }
    return 1;
  }

  n = s->method->ssl_get_message(
      s, SSL3_ST_SR_CERT_VRFY_A, SSL3_ST_SR_CERT_VRFY_B,
      SSL3_MT_CERTIFICATE_VERIFY, SSL3_RT_MAX_PLAIN_LENGTH,
      ssl_dont_hash_message, &ok);

  if (!ok) {
    return n;
  }

  /* Filter out unsupported certificate types. */
  pkey = X509_get_pubkey(peer);
  if (pkey == NULL) {
    goto err;
  }
  if (!(X509_certificate_type(peer, pkey) & EVP_PKT_SIGN) ||
      (pkey->type != EVP_PKEY_RSA && pkey->type != EVP_PKEY_EC)) {
    al = SSL_AD_UNSUPPORTED_CERTIFICATE;
    OPENSSL_PUT_ERROR(SSL, SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE);
    goto f_err;
  }

  CBS_init(&certificate_verify, s->init_msg, n);

  /* Determine the digest type if needbe. */
  if (SSL_USE_SIGALGS(s) &&
      !tls12_check_peer_sigalg(&md, &al, s, &certificate_verify, pkey)) {
    goto f_err;
  }

  /* Compute the digest. */
  if (!ssl3_cert_verify_hash(s, digest, &digest_length, &md, pkey->type)) {
    goto err;
  }

  /* The handshake buffer is no longer necessary, and we may hash the current
   * message.*/
  if (s->s3->handshake_buffer &&
      !ssl3_digest_cached_records(s, free_handshake_buffer)) {
    goto err;
  }
  if (!ssl3_hash_current_message(s)) {
    goto err;
  }

  /* Parse and verify the signature. */
  if (!CBS_get_u16_length_prefixed(&certificate_verify, &signature) ||
      CBS_len(&certificate_verify) != 0) {
    al = SSL_AD_DECODE_ERROR;
    OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
    goto f_err;
  }

  pctx = EVP_PKEY_CTX_new(pkey, NULL);
  if (pctx == NULL) {
    goto err;
  }
  if (!EVP_PKEY_verify_init(pctx) ||
      !EVP_PKEY_CTX_set_signature_md(pctx, md) ||
      !EVP_PKEY_verify(pctx, CBS_data(&signature), CBS_len(&signature), digest,
                       digest_length)) {
    al = SSL_AD_DECRYPT_ERROR;
    OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SIGNATURE);
    goto f_err;
  }

  ret = 1;

  if (0) {
  f_err:
    ssl3_send_alert(s, SSL3_AL_FATAL, al);
  }

err:
  EVP_PKEY_CTX_free(pctx);
  EVP_PKEY_free(pkey);

  return ret;
}

int ssl3_get_client_certificate(SSL *s) {
  int i, ok, al, ret = -1;
  X509 *x = NULL;
  unsigned long n;
  STACK_OF(X509) *sk = NULL;
  SHA256_CTX sha256;
  CBS certificate_msg, certificate_list;
  int is_first_certificate = 1;

  n = s->method->ssl_get_message(s, SSL3_ST_SR_CERT_A, SSL3_ST_SR_CERT_B, -1,
                                 (long)s->max_cert_list, ssl_hash_message, &ok);

  if (!ok) {
    return n;
  }

  if (s->s3->tmp.message_type == SSL3_MT_CLIENT_KEY_EXCHANGE) {
    if ((s->verify_mode & SSL_VERIFY_PEER) &&
        (s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) {
      OPENSSL_PUT_ERROR(SSL, SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE);
      al = SSL_AD_HANDSHAKE_FAILURE;
      goto f_err;
    }

    /* If tls asked for a client cert, the client must return a 0 list */
    if (s->version > SSL3_VERSION && s->s3->tmp.cert_request) {
      OPENSSL_PUT_ERROR(SSL,
                        SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST);
      al = SSL_AD_UNEXPECTED_MESSAGE;
      goto f_err;
    }
    s->s3->tmp.reuse_message = 1;

    return 1;
  }

  if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE) {
    al = SSL_AD_UNEXPECTED_MESSAGE;
    OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_MESSAGE_TYPE);
    goto f_err;
  }

  CBS_init(&certificate_msg, s->init_msg, n);

  sk = sk_X509_new_null();
  if (sk == NULL) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
    goto err;
  }

  if (!CBS_get_u24_length_prefixed(&certificate_msg, &certificate_list) ||
      CBS_len(&certificate_msg) != 0) {
    al = SSL_AD_DECODE_ERROR;
    OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
    goto f_err;
  }

  while (CBS_len(&certificate_list) > 0) {
    CBS certificate;
    const uint8_t *data;

    if (!CBS_get_u24_length_prefixed(&certificate_list, &certificate)) {
      al = SSL_AD_DECODE_ERROR;
      OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
      goto f_err;
    }

    if (is_first_certificate && s->ctx->retain_only_sha256_of_client_certs) {
      /* If this is the first certificate, and we don't want to keep peer
       * certificates in memory, then we hash it right away. */
      SHA256_Init(&sha256);
      SHA256_Update(&sha256, CBS_data(&certificate), CBS_len(&certificate));
      SHA256_Final(s->session->peer_sha256, &sha256);
      s->session->peer_sha256_valid = 1;
    }
    is_first_certificate = 0;

    data = CBS_data(&certificate);
    x = d2i_X509(NULL, &data, CBS_len(&certificate));
    if (x == NULL) {
      al = SSL_AD_BAD_CERTIFICATE;
      OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB);
      goto f_err;
    }
    if (data != CBS_data(&certificate) + CBS_len(&certificate)) {
      al = SSL_AD_DECODE_ERROR;
      OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_LENGTH_MISMATCH);
      goto f_err;
    }
    if (!sk_X509_push(sk, x)) {
      OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
      goto err;
    }
    x = NULL;
  }

  if (sk_X509_num(sk) <= 0) {
    /* TLS does not mind 0 certs returned */
    if (s->version == SSL3_VERSION) {
      al = SSL_AD_HANDSHAKE_FAILURE;
      OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATES_RETURNED);
      goto f_err;
    }
    /* Fail for TLS only if we required a certificate */
    else if ((s->verify_mode & SSL_VERIFY_PEER) &&
             (s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) {
      OPENSSL_PUT_ERROR(SSL, SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE);
      al = SSL_AD_HANDSHAKE_FAILURE;
      goto f_err;
    }
    /* No client certificate so digest cached records */
    if (s->s3->handshake_buffer &&
        !ssl3_digest_cached_records(s, free_handshake_buffer)) {
      al = SSL_AD_INTERNAL_ERROR;
      goto f_err;
    }
  } else {
    i = ssl_verify_cert_chain(s, sk);
    if (i <= 0) {
      al = ssl_verify_alarm_type(s->verify_result);
      OPENSSL_PUT_ERROR(SSL, SSL_R_CERTIFICATE_VERIFY_FAILED);
      goto f_err;
    }
  }

  X509_free(s->session->peer);
  s->session->peer = sk_X509_shift(sk);
  s->session->verify_result = s->verify_result;

  /* With the current implementation, sess_cert will always be NULL when we
   * arrive here. */
  if (s->session->sess_cert == NULL) {
    s->session->sess_cert = ssl_sess_cert_new();
    if (s->session->sess_cert == NULL) {
      OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
      goto err;
    }
  }
  sk_X509_pop_free(s->session->sess_cert->cert_chain, X509_free);
  s->session->sess_cert->cert_chain = sk;
  /* Inconsistency alert: cert_chain does *not* include the peer's own
   * certificate, while we do include it in s3_clnt.c */

  sk = NULL;

  ret = 1;

  if (0) {
  f_err:
    ssl3_send_alert(s, SSL3_AL_FATAL, al);
  }

err:
  X509_free(x);
  sk_X509_pop_free(sk, X509_free);
  return ret;
}

int ssl3_send_server_certificate(SSL *s) {
  if (s->state == SSL3_ST_SW_CERT_A) {
    if (!ssl3_output_cert_chain(s)) {
      return 0;
    }
    s->state = SSL3_ST_SW_CERT_B;
  }

  /* SSL3_ST_SW_CERT_B */
  return ssl_do_write(s);
}

/* send a new session ticket (not necessarily for a new session) */
int ssl3_send_new_session_ticket(SSL *s) {
  int ret = -1;
  uint8_t *session = NULL;
  size_t session_len;
  EVP_CIPHER_CTX ctx;
  HMAC_CTX hctx;

  EVP_CIPHER_CTX_init(&ctx);
  HMAC_CTX_init(&hctx);

  if (s->state == SSL3_ST_SW_SESSION_TICKET_A) {
    uint8_t *p, *macstart;
    int len;
    unsigned int hlen;
    SSL_CTX *tctx = s->initial_ctx;
    uint8_t iv[EVP_MAX_IV_LENGTH];
    uint8_t key_name[16];
    /* The maximum overhead of encrypting the session is 16 (key name) + IV +
     * one block of encryption overhead + HMAC.  */
    const size_t max_ticket_overhead =
        16 + EVP_MAX_IV_LENGTH + EVP_MAX_BLOCK_LENGTH + EVP_MAX_MD_SIZE;

    /* Serialize the SSL_SESSION to be encoded into the ticket. */
    if (!SSL_SESSION_to_bytes_for_ticket(s->session, &session, &session_len)) {
      goto err;
    }

    /* If the session is too long, emit a dummy value rather than abort the
     * connection. */
    if (session_len > 0xFFFF - max_ticket_overhead) {
      static const char kTicketPlaceholder[] = "TICKET TOO LARGE";
      const size_t placeholder_len = strlen(kTicketPlaceholder);

      OPENSSL_free(session);
      session = NULL;

      p = ssl_handshake_start(s);
      /* Emit ticket_lifetime_hint. */
      l2n(0, p);
      /* Emit ticket. */
      s2n(placeholder_len, p);
      memcpy(p, kTicketPlaceholder, placeholder_len);
      p += placeholder_len;

      len = p - ssl_handshake_start(s);
      if (!ssl_set_handshake_header(s, SSL3_MT_NEWSESSION_TICKET, len)) {
        goto err;
      }
      s->state = SSL3_ST_SW_SESSION_TICKET_B;
      return ssl_do_write(s);
    }

    /* Grow buffer if need be: the length calculation is as follows:
     * handshake_header_length + 4 (ticket lifetime hint) + 2 (ticket length) +
     * max_ticket_overhead + * session_length */
    if (!BUF_MEM_grow(s->init_buf, SSL_HM_HEADER_LENGTH(s) + 6 +
                                       max_ticket_overhead + session_len)) {
      goto err;
    }
    p = ssl_handshake_start(s);
    /* Initialize HMAC and cipher contexts. If callback present it does all the
     * work otherwise use generated values from parent ctx. */
    if (tctx->tlsext_ticket_key_cb) {
      if (tctx->tlsext_ticket_key_cb(s, key_name, iv, &ctx, &hctx,
                                     1 /* encrypt */) < 0) {
        goto err;
      }
    } else {
      if (!RAND_bytes(iv, 16) ||
          !EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL,
                              tctx->tlsext_tick_aes_key, iv) ||
          !HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16, tlsext_tick_md(),
                        NULL)) {
        goto err;
      }
      memcpy(key_name, tctx->tlsext_tick_key_name, 16);
    }

    /* Ticket lifetime hint (advisory only): We leave this unspecified for
     * resumed session (for simplicity), and guess that tickets for new
     * sessions will live as long as their sessions. */
    l2n(s->hit ? 0 : s->session->timeout, p);

    /* Skip ticket length for now */
    p += 2;
    /* Output key name */
    macstart = p;
    memcpy(p, key_name, 16);
    p += 16;
    /* output IV */
    memcpy(p, iv, EVP_CIPHER_CTX_iv_length(&ctx));
    p += EVP_CIPHER_CTX_iv_length(&ctx);
    /* Encrypt session data */
    if (!EVP_EncryptUpdate(&ctx, p, &len, session, session_len)) {
      goto err;
    }
    p += len;
    if (!EVP_EncryptFinal_ex(&ctx, p, &len)) {
      goto err;
    }
    p += len;

    if (!HMAC_Update(&hctx, macstart, p - macstart) ||
        !HMAC_Final(&hctx, p, &hlen)) {
      goto err;
    }

    p += hlen;
    /* Now write out lengths: p points to end of data written */
    /* Total length */
    len = p - ssl_handshake_start(s);
    /* Skip ticket lifetime hint */
    p = ssl_handshake_start(s) + 4;
    s2n(len - 6, p);
    if (!ssl_set_handshake_header(s, SSL3_MT_NEWSESSION_TICKET, len)) {
      goto err;
    }
    s->state = SSL3_ST_SW_SESSION_TICKET_B;
  }

  /* SSL3_ST_SW_SESSION_TICKET_B */
  ret = ssl_do_write(s);

err:
  OPENSSL_free(session);
  EVP_CIPHER_CTX_cleanup(&ctx);
  HMAC_CTX_cleanup(&hctx);
  return ret;
}

/* ssl3_get_next_proto reads a Next Protocol Negotiation handshake message. It
 * sets the next_proto member in s if found */
int ssl3_get_next_proto(SSL *s) {
  int ok;
  long n;
  CBS next_protocol, selected_protocol, padding;

  /* Clients cannot send a NextProtocol message if we didn't see the extension
   * in their ClientHello */
  if (!s->s3->next_proto_neg_seen) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION);
    return -1;
  }

  n = s->method->ssl_get_message(s, SSL3_ST_SR_NEXT_PROTO_A,
                                 SSL3_ST_SR_NEXT_PROTO_B, SSL3_MT_NEXT_PROTO,
                                 514, /* See the payload format below */
                                 ssl_hash_message, &ok);

  if (!ok) {
    return n;
  }

  /* s->state doesn't reflect whether ChangeCipherSpec has been received in
   * this handshake, but s->s3->change_cipher_spec does (will be reset by
   * ssl3_get_finished).
   *
   * TODO(davidben): Is this check now redundant with
   * SSL3_FLAGS_EXPECT_CCS? */
  if (!s->s3->change_cipher_spec) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS);
    return -1;
  }

  CBS_init(&next_protocol, s->init_msg, n);

  /* The payload looks like:
   *   uint8 proto_len;
   *   uint8 proto[proto_len];
   *   uint8 padding_len;
   *   uint8 padding[padding_len]; */
  if (!CBS_get_u8_length_prefixed(&next_protocol, &selected_protocol) ||
      !CBS_get_u8_length_prefixed(&next_protocol, &padding) ||
      CBS_len(&next_protocol) != 0 ||
      !CBS_stow(&selected_protocol, &s->next_proto_negotiated,
                &s->next_proto_negotiated_len)) {
    return 0;
  }

  return 1;
}

/* ssl3_get_channel_id reads and verifies a ClientID handshake message. */
int ssl3_get_channel_id(SSL *s) {
  int ret = -1, ok;
  long n;
  EVP_MD_CTX md_ctx;
  uint8_t channel_id_hash[SHA256_DIGEST_LENGTH];
  unsigned int channel_id_hash_len;
  const uint8_t *p;
  uint16_t extension_type, expected_extension_type;
  EC_GROUP *p256 = NULL;
  EC_KEY *key = NULL;
  EC_POINT *point = NULL;
  ECDSA_SIG sig;
  BIGNUM x, y;
  CBS encrypted_extensions, extension;

  n = s->method->ssl_get_message(
      s, SSL3_ST_SR_CHANNEL_ID_A, SSL3_ST_SR_CHANNEL_ID_B,
      SSL3_MT_ENCRYPTED_EXTENSIONS, 2 + 2 + TLSEXT_CHANNEL_ID_SIZE,
      ssl_dont_hash_message, &ok);

  if (!ok) {
    return n;
  }

  /* Before incorporating the EncryptedExtensions message to the handshake
   * hash, compute the hash that should have been signed. */
  channel_id_hash_len = sizeof(channel_id_hash);
  EVP_MD_CTX_init(&md_ctx);
  if (!EVP_DigestInit_ex(&md_ctx, EVP_sha256(), NULL) ||
      !tls1_channel_id_hash(&md_ctx, s) ||
      !EVP_DigestFinal(&md_ctx, channel_id_hash, &channel_id_hash_len)) {
    EVP_MD_CTX_cleanup(&md_ctx);
    return -1;
  }
  EVP_MD_CTX_cleanup(&md_ctx);
  assert(channel_id_hash_len == SHA256_DIGEST_LENGTH);

  if (!ssl3_hash_current_message(s)) {
    return -1;
  }

  /* s->state doesn't reflect whether ChangeCipherSpec has been received in
   * this handshake, but s->s3->change_cipher_spec does (will be reset by
   * ssl3_get_finished).
   *
   * TODO(davidben): Is this check now redundant with SSL3_FLAGS_EXPECT_CCS? */
  if (!s->s3->change_cipher_spec) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_GOT_CHANNEL_ID_BEFORE_A_CCS);
    return -1;
  }

  CBS_init(&encrypted_extensions, s->init_msg, n);

  /* EncryptedExtensions could include multiple extensions, but the only
   * extension that could be negotiated is ChannelID, so there can only be one
   * entry.
   *
   * The payload looks like:
   *   uint16 extension_type
   *   uint16 extension_len;
   *   uint8 x[32];
   *   uint8 y[32];
   *   uint8 r[32];
   *   uint8 s[32]; */
  expected_extension_type = TLSEXT_TYPE_channel_id;
  if (s->s3->tlsext_channel_id_new) {
    expected_extension_type = TLSEXT_TYPE_channel_id_new;
  }

  if (!CBS_get_u16(&encrypted_extensions, &extension_type) ||
      !CBS_get_u16_length_prefixed(&encrypted_extensions, &extension) ||
      CBS_len(&encrypted_extensions) != 0 ||
      extension_type != expected_extension_type ||
      CBS_len(&extension) != TLSEXT_CHANNEL_ID_SIZE) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_MESSAGE);
    return -1;
  }

  p256 = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
  if (!p256) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_NO_P256_SUPPORT);
    return -1;
  }

  BN_init(&x);
  BN_init(&y);
  sig.r = BN_new();
  sig.s = BN_new();
  if (sig.r == NULL || sig.s == NULL) {
    goto err;
  }

  p = CBS_data(&extension);
  if (BN_bin2bn(p + 0, 32, &x) == NULL ||
      BN_bin2bn(p + 32, 32, &y) == NULL ||
      BN_bin2bn(p + 64, 32, sig.r) == NULL ||
      BN_bin2bn(p + 96, 32, sig.s) == NULL) {
    goto err;
  }

  point = EC_POINT_new(p256);
  if (!point || !EC_POINT_set_affine_coordinates_GFp(p256, point, &x, &y, NULL)) {
    goto err;
  }

  key = EC_KEY_new();
  if (!key || !EC_KEY_set_group(key, p256) ||
      !EC_KEY_set_public_key(key, point)) {
    goto err;
  }

  /* We stored the handshake hash in |tlsext_channel_id| the first time that we
   * were called. */
  if (!ECDSA_do_verify(channel_id_hash, channel_id_hash_len, &sig, key)) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_CHANNEL_ID_SIGNATURE_INVALID);
    s->s3->tlsext_channel_id_valid = 0;
    goto err;
  }

  memcpy(s->s3->tlsext_channel_id, p, 64);
  ret = 1;

err:
  BN_free(&x);
  BN_free(&y);
  BN_free(sig.r);
  BN_free(sig.s);
  EC_KEY_free(key);
  EC_POINT_free(point);
  EC_GROUP_free(p256);
  return ret;
}
