/* 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) {
          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->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;
  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]; */

  if (!CBS_get_u16(&encrypted_extensions, &extension_type) ||
      !CBS_get_u16_length_prefixed(&encrypted_extensions, &extension) ||
      CBS_len(&encrypted_extensions) != 0 ||
      extension_type != TLSEXT_TYPE_channel_id ||
      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;
}
