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

#define NETSCAPE_HANG_BUG

#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/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 "ssl_locl.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;
  unsigned long 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, ssl3_accept, SSL_R_NO_CERTIFICATE_SET);
    return -1;
  }

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

    switch (s->state) {
      case SSL_ST_RENEGOTIATE:
        /* This state is the renegotiate entry point. It sends a HelloRequest
         * and nothing else. */
        s->renegotiate = 1;

        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;

        if (!ssl3_setup_buffers(s)) {
          ret = -1;
          goto end;
        }

        if (!s->s3->send_connection_binding &&
            !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) {
          /* Server attempting to renegotiate with client that doesn't support
           * secure renegotiation. */
          OPENSSL_PUT_ERROR(SSL, ssl3_accept,
                            SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
          ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
          ret = -1;
          goto end;
        }

        s->ctx->stats.sess_accept_renegotiate++;
        s->state = SSL3_ST_SW_HELLO_REQ_A;
        break;

      case SSL3_ST_SW_HELLO_REQ_A:
      case SSL3_ST_SW_HELLO_REQ_B:
        s->shutdown = 0;
        ret = ssl3_send_hello_request(s);
        if (ret <= 0) {
          goto end;
        }
        s->s3->tmp.next_state = SSL3_ST_SW_HELLO_REQ_C;
        s->state = SSL3_ST_SW_FLUSH;
        s->init_num = 0;

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

      case SSL3_ST_SW_HELLO_REQ_C:
        s->state = SSL_ST_OK;
        break;

      case SSL_ST_ACCEPT:
      case SSL_ST_BEFORE | SSL_ST_ACCEPT:
        /* This state is the entry point for the handshake itself (initial and
         * renegotiation).  */
        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;

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

        if (!s->s3->have_version) {
          /* This is the initial handshake. The record layer has not been
           * initialized yet. Sniff for a V2ClientHello before reading a
           * ClientHello normally. */
          assert(s->s3->rbuf.buf == NULL);
          assert(s->s3->wbuf.buf == NULL);
          s->state = SSL3_ST_SR_INITIAL_BYTES;
        } else {
          /* Enable a write buffer. This groups handshake messages within a
           * flight into a single write. */
          if (!ssl3_setup_buffers(s) || !ssl_init_wbio_buffer(s, 1)) {
            ret = -1;
            goto end;
          }
          s->state = SSL3_ST_SR_CLNT_HELLO_A;
        }
        s->ctx->stats.sess_accept++;
        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 == PENDING_SESSION) {
          s->rwstate = SSL_PENDING_SESSION;
          goto end;
        }
        if (ret == CERTIFICATE_SELECTION_PENDING) {
          s->rwstate = SSL_CERTIFICATE_SELECTION_PENDING;
          goto end;
        }
        if (ret <= 0) {
          goto end;
        }
        s->renegotiate = 2;
        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 (/* don't request cert unless asked for it: */
            !(s->verify_mode & SSL_VERIFY_PEER) ||
            /* Don't request a certificate if an obc was presented */
            ((s->verify_mode & SSL_VERIFY_PEER_IF_NO_OBC) &&
             s->s3->tlsext_channel_id_valid) ||
            /* if SSL_VERIFY_CLIENT_ONCE is set,
             * don't request cert during re-negotiation: */
            ((s->session->peer != NULL) &&
             (s->verify_mode & SSL_VERIFY_CLIENT_ONCE)) ||
            /* never request cert in anonymous ciphersuites
             * (see section "Certificate request" in SSL 3 drafts
             * and in RFC 2246): */
            ((s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) &&
             /* ... except when the application insists on verification
              * (against the specs, but s3_clnt.c accepts this for SSL 3) */
             !(s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) ||
            /* With normal PSK Certificates and
             * Certificate Requests are omitted */
            (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) {
          /* no cert request */
          skip = 1;
          s->s3->tmp.cert_request = 0;
          s->state = SSL3_ST_SW_SRVR_DONE_A;
          if (s->s3->handshake_buffer &&
              !ssl3_digest_cached_records(s, free_handshake_buffer)) {
            return -1;
          }
        } else {
          s->s3->tmp.cert_request = 1;
          ret = ssl3_send_certificate_request(s);
          if (ret <= 0) {
            goto end;
          }
#ifndef NETSCAPE_HANG_BUG
          s->state = SSL3_ST_SW_SRVR_DONE_A;
#else
          /* ServerHelloDone was already sent in the
           * previous record. */
          s->state = SSL3_ST_SW_FLUSH;
          s->s3->tmp.next_state = SSL3_ST_SR_CERT_A;
#endif
          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->session->peer && s->ctx->retain_only_sha256_of_client_certs) {
          X509_free(s->session->peer);
          s->session->peer = NULL;
        }

        if (s->renegotiate == 2) {
          /* skipped if we just sent a HelloRequest */
          s->renegotiate = 0;
          s->new_session = 0;

          ssl_update_cache(s, SSL_SESS_CACHE_SERVER);

          s->ctx->stats.sess_accept_good++;

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

        ret = 1;
        goto end;

      default:
        OPENSSL_PUT_ERROR(SSL, ssl3_accept, 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--;
  if (buf != NULL) {
    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, ssl3_get_initial_bytes, SSL_R_HTTP_REQUEST);
    return -1;
  }
  if (strncmp("CONNECT ", (const char *)p, 8) == 0) {
    OPENSSL_PUT_ERROR(SSL, ssl3_get_initial_bytes, 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_buffers(s) || !ssl_init_wbio_buffer(s, 1)) {
      return -1;
    }
    assert(s->rstate == SSL_ST_READ_HEADER);
    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, ssl3_get_initial_bytes, 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, ssl3_get_v2_client_hello, 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, ssl3_get_v2_client_hello,
                      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. */
  ssl3_finish_mac(s, CBS_data(&v2_client_hello), CBS_len(&v2_client_hello));
  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, ssl3_get_v2_client_hello, 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. */
  if (!CBB_init_fixed(&client_hello, (uint8_t *)s->init_buf->data,
                      s->init_buf->max)) {
    OPENSSL_PUT_ERROR(SSL, ssl3_get_v2_client_hello, ERR_R_MALLOC_FAILURE);
    return -1;
  }
  if (!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, ssl3_get_v2_client_hello, ERR_R_INTERNAL_ERROR);
    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, ssl3_get_v2_client_hello, 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, ssl3_get_v2_client_hello, 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, ssl3_get_v2_client_hello, 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;

  /* Initialize the record layer. */
  if (!ssl3_setup_buffers(s) || !ssl_init_wbio_buffer(s, 1)) {
    return -1;
  }

  /* 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_send_hello_request(SSL *s) {
  if (s->state == SSL3_ST_SW_HELLO_REQ_A) {
    ssl_set_handshake_header(s, SSL3_MT_HELLO_REQUEST, 0);
    s->state = SSL3_ST_SW_HELLO_REQ_B;
  }

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

int ssl3_get_client_hello(SSL *s) {
  int i, 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;

  /* 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_GET_MESSAGE_HASH_MESSAGE, &ok);

      if (!ok) {
        return n;
      }

      /* If we require cookies and this ClientHello doesn't contain one, just
       * return since we do not want to allocate any memory yet. So check
       * cookie length... */
      if (SSL_IS_DTLS(s) && (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE)) {
        uint8_t cookie_length;

        CBS_init(&client_hello, s->init_msg, n);
        if (!CBS_skip(&client_hello, 2 + SSL3_RANDOM_SIZE) ||
            !CBS_get_u8_length_prefixed(&client_hello, &session_id) ||
            !CBS_get_u8(&client_hello, &cookie_length)) {
          al = SSL_AD_DECODE_ERROR;
          OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello, SSL_R_DECODE_ERROR);
          goto f_err;
        }

        if (cookie_length == 0) {
          return 1;
        }
      }
      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, ssl3_get_client_hello,
                          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:
            return CERTIFICATE_SELECTION_PENDING;

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

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

    default:
      OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello, 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, ssl3_get_client_hello, 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, ssl3_get_client_hello, SSL_R_DECODE_ERROR);
      goto f_err;
    }

    /* Verify the cookie if appropriate option is set. */
    if ((SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE) && CBS_len(&cookie) > 0) {
      if (s->ctx->app_verify_cookie_cb != NULL) {
        if (s->ctx->app_verify_cookie_cb(s, CBS_data(&cookie),
                                         CBS_len(&cookie)) == 0) {
          al = SSL_AD_HANDSHAKE_FAILURE;
          OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello, SSL_R_COOKIE_MISMATCH);
          goto f_err;
        }
        /* else cookie verification succeeded */
      } else if (!CBS_mem_equal(&cookie, s->d1->cookie, s->d1->cookie_len)) {
        /* default verification */
        al = SSL_AD_HANDSHAKE_FAILURE;
        OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello, SSL_R_COOKIE_MISMATCH);
        goto f_err;
      }
      /* Set to -2 so if successful we return 2 and don't send
       * HelloVerifyRequest. */
      ret = -2;
    }
  }

  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, ssl3_get_client_hello, 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, ssl3_get_client_hello, SSL_R_WRONG_VERSION_NUMBER);
    al = SSL_AD_PROTOCOL_VERSION;
    goto f_err;
  }

  s->hit = 0;
  /* Versions before 0.9.7 always allow clients to resume sessions in
   * renegotiation. 0.9.7 and later allow this by default, but optionally
   * ignore resumption requests with flag
   * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION (it's a new flag rather than
   * a change to default behavior so that applications relying on this for
   * security won't even compile against older library versions).
   *
   * 1.0.1 and later also have a function SSL_renegotiate_abbreviated() to
   * request renegotiation but not a new session (s->new_session remains
   * unset): for servers, this essentially just means that the
   * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION setting will be ignored. */
  if (s->new_session &&
      (s->options & SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION)) {
    if (!ssl_get_new_session(s, 1)) {
      goto err;
    }
  } else {
    i = ssl_get_prev_session(s, &early_ctx);
    if (i == PENDING_SESSION) {
      ret = PENDING_SESSION;
      goto err;
    } else if (i == -1) {
      goto err;
    }

    /* Only resume if the session's version matches the negotiated version:
     * most clients do not accept a mismatch. */
    if (i == 1 && s->version == s->session->ssl_version) {
      s->hit = 1;
    } else {
      /* No session was found or it was unacceptable. */
      if (!ssl_get_new_session(s, 1)) {
        goto err;
      }
    }
  }

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

  /* TODO(davidben): Per spec, cipher_suites can never be empty (specified at
   * the ClientHello structure level). This logic allows it to be empty if
   * resuming a session. Can we always require non-empty? If a client sends
   * empty cipher_suites because it's resuming a session, it could always fail
   * to resume a session, so it's unlikely to actually work. */
  if (CBS_len(&cipher_suites) == 0 && CBS_len(&session_id) != 0) {
    /* We need a cipher if we are not resuming a session. */
    al = SSL_AD_ILLEGAL_PARAMETER;
    OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello, SSL_R_NO_CIPHERS_SPECIFIED);
    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 && CBS_len(&cipher_suites) > 0) {
    size_t j;
    int found_cipher = 0;
    unsigned long 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, ssl3_get_client_hello,
                        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, ssl3_get_client_hello,
                      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, ssl3_get_client_hello, 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, ssl3_get_client_hello, SSL_R_BAD_PACKET_LENGTH);
    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, ssl3_get_client_hello, 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, ssl3_get_client_hello, 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, ssl3_get_client_hello, SSL_R_NO_SHARED_CIPHER);
      goto f_err;
    }
    s->s3->tmp.new_cipher = c;
  } else {
    /* Session-id reuse */
    s->s3->tmp.new_cipher = s->session->cipher;
  }

  if ((!SSL_USE_SIGALGS(s) || !(s->verify_mode & SSL_VERIFY_PEER)) &&
      !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:
  if (ciphers != NULL) {
    sk_SSL_CIPHER_free(ciphers);
  }
  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_kEECDH) == 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, 1, s->s3->server_random, SSL3_RANDOM_SIZE)) {
      OPENSSL_PUT_ERROR(SSL, ssl3_send_server_hello, 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, ssl3_send_server_hello, ERR_R_INTERNAL_ERROR);
      return -1;
    }
    *(p++) = sl;
    memcpy(p, s->session->session_id, sl);
    p += sl;

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

    /* put the compression method */
    *(p++) = 0;
    if (ssl_prepare_serverhello_tlsext(s) <= 0) {
      OPENSSL_PUT_ERROR(SSL, ssl3_send_server_hello, 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, ssl3_send_server_hello, ERR_R_INTERNAL_ERROR);
      return -1;
    }

    /* do the header */
    l = (p - d);
    ssl_set_handshake_header(s, SSL3_MT_SERVER_HELLO, l);
    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) {
    ssl_set_handshake_header(s, SSL3_MT_SERVER_DONE, 0);
    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, *ecdhp;
  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;
  unsigned long alg_k;
  unsigned long 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_kEDH) {
      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, ssl3_send_server_key_exchange,
                          SSL_R_MISSING_TMP_DH_KEY);
        goto f_err;
      }

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

      dh = DHparams_dup(dhp);
      if (dh == NULL) {
        OPENSSL_PUT_ERROR(SSL, ssl3_send_server_key_exchange, ERR_R_DH_LIB);
        goto err;
      }

      s->s3->tmp.dh = dh;
      if (dhp->pub_key == NULL || dhp->priv_key == NULL ||
          (s->options & SSL_OP_SINGLE_DH_USE)) {
        if (!DH_generate_key(dh)) {
          OPENSSL_PUT_ERROR(SSL, ssl3_send_server_key_exchange, ERR_R_DH_LIB);
          goto err;
        }
      } else {
        dh->pub_key = BN_dup(dhp->pub_key);
        dh->priv_key = BN_dup(dhp->priv_key);
        if (dh->pub_key == NULL || dh->priv_key == NULL) {
          OPENSSL_PUT_ERROR(SSL, ssl3_send_server_key_exchange, ERR_R_DH_LIB);
          goto err;
        }
      }

      r[0] = dh->p;
      r[1] = dh->g;
      r[2] = dh->pub_key;
    } else if (alg_k & SSL_kEECDH) {
      const EC_GROUP *group;

      ecdhp = cert->ecdh_tmp;
      if (s->cert->ecdh_tmp_auto) {
        /* Get NID of appropriate shared curve */
        int nid = tls1_get_shared_curve(s);
        if (nid != NID_undef) {
          ecdhp = EC_KEY_new_by_curve_name(nid);
        }
      } else if (ecdhp == NULL && s->cert->ecdh_tmp_cb) {
        ecdhp = s->cert->ecdh_tmp_cb(s, 0, 1024);
      }
      if (ecdhp == NULL) {
        al = SSL_AD_HANDSHAKE_FAILURE;
        OPENSSL_PUT_ERROR(SSL, ssl3_send_server_key_exchange,
                          SSL_R_MISSING_TMP_ECDH_KEY);
        goto f_err;
      }

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

      /* Duplicate the ECDH structure. */
      if (ecdhp == NULL) {
        OPENSSL_PUT_ERROR(SSL, ssl3_send_server_key_exchange, ERR_R_ECDH_LIB);
        goto err;
      }

      if (s->cert->ecdh_tmp_auto) {
        ecdh = ecdhp;
      } else {
        ecdh = EC_KEY_dup(ecdhp);
        if (ecdh == NULL) {
          OPENSSL_PUT_ERROR(SSL, ssl3_send_server_key_exchange, ERR_R_ECDH_LIB);
          goto err;
        }
      }

      s->s3->tmp.ecdh = ecdh;
      if (EC_KEY_get0_public_key(ecdh) == NULL ||
          EC_KEY_get0_private_key(ecdh) == NULL ||
          (s->options & SSL_OP_SINGLE_ECDH_USE)) {
        if (!EC_KEY_generate_key(ecdh)) {
          OPENSSL_PUT_ERROR(SSL, ssl3_send_server_key_exchange, ERR_R_ECDH_LIB);
          goto err;
        }
      }

      group = EC_KEY_get0_group(ecdh);
      if (group == NULL ||
          EC_KEY_get0_public_key(ecdh) == NULL ||
          EC_KEY_get0_private_key(ecdh) == NULL) {
        OPENSSL_PUT_ERROR(SSL, ssl3_send_server_key_exchange, ERR_R_ECDH_LIB);
        goto err;
      }

      /* We only support ephemeral ECDH keys over named (not generic) curves. */
      if (!tls1_ec_nid2curve_id(&curve_id, EC_GROUP_get_curve_name(group))) {
        OPENSSL_PUT_ERROR(SSL, ssl3_send_server_key_exchange,
                          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, ssl3_send_server_key_exchange,
                          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, ssl3_send_server_key_exchange, 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, ssl3_send_server_key_exchange,
                        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 = ssl_get_sign_pkey(s, s->s3->tmp.new_cipher);
      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, ssl3_send_server_key_exchange, 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_kEECDH 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_kEECDH) {
      /* 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, pkey);
        if (!tls12_get_sigandhash(p, pkey, md)) {
          /* Should never happen */
          al = SSL_AD_INTERNAL_ERROR;
          OPENSSL_PUT_ERROR(SSL, ssl3_send_server_key_exchange,
                            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, ssl3_send_server_key_exchange, ERR_LIB_EVP);
        goto err;
      }

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

    ssl_set_handshake_header(s, SSL3_MT_SERVER_KEY_EXCHANGE, n);
  }

  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:
  if (encodedPoint != NULL) {
    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, ssl3_send_certificate_request, 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);

    ssl_set_handshake_header(s, SSL3_MT_CERTIFICATE_REQUEST, n);

#ifdef NETSCAPE_HANG_BUG
    if (!SSL_IS_DTLS(s)) {
      /* Prepare a ServerHelloDone in the same record. This is to workaround a
       * hang in Netscape. */
      if (!BUF_MEM_grow_clean(buf, s->init_num + 4)) {
        OPENSSL_PUT_ERROR(SSL, ssl3_send_certificate_request, ERR_R_BUF_LIB);
        goto err;
      }
      p = (uint8_t *)s->init_buf->data + s->init_num;
      /* do the header */
      *(p++) = SSL3_MT_SERVER_DONE;
      *(p++) = 0;
      *(p++) = 0;
      *(p++) = 0;
      s->init_num += 4;
      ssl3_finish_mac(s, p - 4, 4);
    }
#endif

    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;
  unsigned long alg_k;
  unsigned long 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_GET_MESSAGE_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, ssl3_get_client_key_exchange, SSL_R_DECODE_ERROR);
      al = SSL_AD_DECODE_ERROR;
      goto f_err;
    }

    if (s->psk_server_callback == NULL) {
      OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange,
                        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, ssl3_get_client_key_exchange,
                        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, ssl3_get_client_key_exchange,
                        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, ssl3_get_client_key_exchange,
                        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, ssl3_get_client_key_exchange,
                        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->pkeys[SSL_PKEY_RSA_ENC].privatekey;
    if (pkey == NULL || pkey->type != EVP_PKEY_RSA || pkey->pkey.rsa == NULL) {
      al = SSL_AD_HANDSHAKE_FAILURE;
      OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange,
                        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, ssl3_get_client_key_exchange,
                            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, ssl3_get_client_key_exchange,
                        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, ssl3_get_client_key_exchange,
                        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, ssl3_get_client_key_exchange,
                        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, ssl3_get_client_key_exchange,
                        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_kEDH) {
    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, ssl3_get_client_key_exchange,
                        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, ssl3_get_client_key_exchange,
                        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, ssl3_get_client_key_exchange, 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, ssl3_get_client_key_exchange,
                        ERR_R_MALLOC_FAILURE);
      goto err;
    }

    dh_len = DH_compute_key(premaster_secret, pub, dh_srvr);
    if (dh_len <= 0) {
      OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, 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_kEECDH) {
    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, ssl3_get_client_key_exchange,
                        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, ssl3_get_client_key_exchange, 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, ssl3_get_client_key_exchange,
                        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, ssl3_get_client_key_exchange, SSL_R_DECODE_ERROR);
      goto f_err;
    }

    bn_ctx = BN_CTX_new();
    if (bn_ctx == NULL) {
      OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange,
                        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, ssl3_get_client_key_exchange, 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, ssl3_get_client_key_exchange, 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, ssl3_get_client_key_exchange,
                        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, ssl3_get_client_key_exchange, 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, ssl3_get_client_key_exchange,
                        ERR_R_MALLOC_FAILURE);
      goto err;
    }
    memset(premaster_secret, 0, premaster_secret_len);
  } else {
    al = SSL_AD_HANDSHAKE_FAILURE;
    OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange,
                      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;

    if (!CBB_init(&new_premaster, 2 + psk_len + 2 + premaster_secret_len)) {
      OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange,
                        ERR_R_MALLOC_FAILURE);
      goto err;
    }
    if (!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, ssl3_get_client_key_exchange,
                        ERR_R_INTERNAL_ERROR);
      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);
  }
  if (decrypt_buf) {
    OPENSSL_free(decrypt_buf);
  }
  EVP_PKEY_free(clnt_pub_pkey);
  EC_POINT_free(clnt_ecpoint);
  if (srvr_ecdh != NULL) {
    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_GET_MESSAGE_DONT_HASH_MESSAGE, &ok);

  if (!ok) {
    return n;
  }

  /* Filter out unsupported certificate types. */
  pkey = X509_get_pubkey(peer);
  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, ssl3_get_cert_verify,
                      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)) {
    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;
  }
  ssl3_hash_current_message(s);

  /* 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, ssl3_get_cert_verify, 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, ssl3_get_cert_verify, 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,
                                 s->max_cert_list, SSL_GET_MESSAGE_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, ssl3_get_client_certificate,
                        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, ssl3_get_client_certificate,
                        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, ssl3_get_client_certificate,
                      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, ssl3_get_client_certificate, 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, ssl3_get_client_certificate, 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, ssl3_get_client_certificate, 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, ssl3_get_client_certificate, ERR_R_ASN1_LIB);
      goto f_err;
    }
    if (data != CBS_data(&certificate) + CBS_len(&certificate)) {
      al = SSL_AD_DECODE_ERROR;
      OPENSSL_PUT_ERROR(SSL, ssl3_get_client_certificate,
                        SSL_R_CERT_LENGTH_MISMATCH);
      goto f_err;
    }
    if (!sk_X509_push(sk, x)) {
      OPENSSL_PUT_ERROR(SSL, ssl3_get_client_certificate, 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, ssl3_get_client_certificate,
                        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, ssl3_get_client_certificate,
                        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, ssl3_get_client_certificate,
                        SSL_R_CERTIFICATE_VERIFY_FAILED);
      goto f_err;
    }
  }

  if (s->session->peer != NULL) {
    /* This should not be needed */
    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, ssl3_get_client_certificate, ERR_R_MALLOC_FAILURE);
      goto err;
    }
  }
  if (s->session->sess_cert->cert_chain != NULL) {
    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:
  if (x != NULL) {
    X509_free(x);
  }
  if (sk != NULL) {
    sk_X509_pop_free(sk, X509_free);
  }
  return ret;
}

int ssl3_send_server_certificate(SSL *s) {
  CERT_PKEY *cpk;

  if (s->state == SSL3_ST_SW_CERT_A) {
    cpk = ssl_get_server_send_pkey(s);
    if (cpk == NULL) {
      OPENSSL_PUT_ERROR(SSL, ssl3_send_server_certificate,
                        ERR_R_INTERNAL_ERROR);
      return 0;
    }

    ssl3_output_cert_chain(s, cpk);
    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) {
  if (s->state == SSL3_ST_SW_SESSION_TICKET_A) {
    uint8_t *session;
    size_t session_len;
    uint8_t *p, *macstart;
    int len;
    unsigned int hlen;
    EVP_CIPHER_CTX ctx;
    HMAC_CTX hctx;
    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)) {
      return -1;
    }

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

      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);
      ssl_set_handshake_header(s, SSL3_MT_NEWSESSION_TICKET, len);
      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)) {
      OPENSSL_free(session);
      return -1;
    }
    p = ssl_handshake_start(s);
    EVP_CIPHER_CTX_init(&ctx);
    HMAC_CTX_init(&hctx);
    /* 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) < 0) {
        OPENSSL_free(session);
        EVP_CIPHER_CTX_cleanup(&ctx);
        HMAC_CTX_cleanup(&hctx);
        return -1;
      }
    } 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)) {
        OPENSSL_free(session);
        EVP_CIPHER_CTX_cleanup(&ctx);
        HMAC_CTX_cleanup(&hctx);
        return -1;
      }
      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 */
    EVP_EncryptUpdate(&ctx, p, &len, session, session_len);
    p += len;
    EVP_EncryptFinal_ex(&ctx, p, &len);
    p += len;
    EVP_CIPHER_CTX_cleanup(&ctx);

    HMAC_Update(&hctx, macstart, p - macstart);
    HMAC_Final(&hctx, p, &hlen);
    HMAC_CTX_cleanup(&hctx);

    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);
    ssl_set_handshake_header(s, SSL3_MT_NEWSESSION_TICKET, len);
    s->state = SSL3_ST_SW_SESSION_TICKET_B;
    OPENSSL_free(session);
  }

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

/* 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, ssl3_get_next_proto,
                      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_GET_MESSAGE_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, ssl3_get_next_proto,
                      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_GET_MESSAGE_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);

  ssl3_hash_current_message(s);

  /* 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, ssl3_get_channel_id,
                      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, ssl3_get_channel_id, SSL_R_INVALID_MESSAGE);
    return -1;
  }

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

  BN_init(&x);
  BN_init(&y);
  sig.r = BN_new();
  sig.s = BN_new();

  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, ssl3_get_channel_id,
                      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);
  if (key) {
    EC_KEY_free(key);
  }
  if (point) {
    EC_POINT_free(point);
  }
  if (p256) {
    EC_GROUP_free(p256);
  }
  return ret;
}
