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

#if 0
		// TODO(davidben): Implement OCSP stapling on the server.
		case SSL3_ST_SW_CERT_STATUS_A:
		case SSL3_ST_SW_CERT_STATUS_B:
			ret=ssl3_send_cert_status(s);
			if (ret <= 0) goto end;
			s->state=SSL3_ST_SW_KEY_EXCH_A;
			s->init_num=0;
			break;
#endif

		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++;
				/* s->server=1; */

				if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_DONE,1);
				}
			
			ret = 1;
			goto end;
			/* break; */

		default:
			OPENSSL_PUT_ERROR(SSL, ssl3_accept, SSL_R_UNKNOWN_STATE);
			ret= -1;
			goto end;
			/* break; */
			}
		
		if (!s->s3->tmp.reuse_message && !skip)
			{
			if ((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:
	/* BIO_flush(s->wbio); */

	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((int)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)
		{
		if (!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))
		{
		if (!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)
	{
	unsigned char *buf;
	unsigned char *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=(unsigned char *)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;
			}
		if ((p = ssl_add_serverhello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == 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;
	unsigned char *encodedPoint = NULL;
	int encodedlen = 0;
	int curve_id = 0;
	BN_CTX *bn_ctx = NULL; 
	const char* psk_identity_hint = NULL;
	size_t psk_identity_hint_len = 0;
	EVP_PKEY *pkey;
	unsigned char *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;
				}

			if ((dh=DHparams_dup(dhp)) == 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 if ((ecdh = EC_KEY_dup(ecdhp)) == 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;
				    }
				}

			if (((group = EC_KEY_get0_group(ecdh)) == 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;
				}

			/* XXX: For now, we only support ephemeral ECDH
			 * keys over named (not generic) curves. For 
			 * supported named curves, curve_id is non-zero.
			 */
			if ((curve_id = 
			    tls1_ec_nid2curve_id(EC_GROUP_get_curve_name(group)))
			    == 0)
				{
				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 = (unsigned char *) 
			    OPENSSL_malloc(encodedlen*sizeof(unsigned char)); 
			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;

			/* XXX: For now, 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))
			{
			if ((pkey=ssl_get_sign_pkey(s,s->s3->tmp.new_cipher))
				== 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)
			{
			/* XXX: For now, 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 += 1;
			*p = 0;
			p += 1;
			*p = curve_id;
			p += 1;
			*p = encodedlen;
			p += 1;
			memcpy((unsigned char*)p, 
			    (unsigned char *)encodedPoint, 
			    encodedlen);
			OPENSSL_free(encodedPoint);
			encodedPoint = NULL;
			p += encodedlen;
			}

		/* 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)
	{
	unsigned char *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 unsigned char *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=(unsigned char *)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;
	unsigned char 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((int)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 */
		if ((srvr_ecdh = EC_KEY_new()) == 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 */
		if ((clnt_ecpoint = EC_POINT_new(group)) == 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;
			}

		if ((bn_ctx = BN_CTX_new()) == 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 (int)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))
		{
		if (!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((int)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);

	if ((sk=sk_X509_new_null()) == 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;
		unsigned char iv[EVP_MAX_IV_LENGTH];
		unsigned char 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)
			{
			const char kTicketPlaceholder[] = "TICKET TOO LARGE";
			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);
	}

#if 0
int ssl3_send_cert_status(SSL *s)
	{
	if (s->state == SSL3_ST_SW_CERT_STATUS_A)
		{
		unsigned char *p;
		/* Grow buffer if need be: the length calculation is as
 		 * follows 1 (message type) + 3 (message length) +
 		 * 1 (ocsp response type) + 3 (ocsp response length)
 		 * + (ocsp response)
 		 */
		if (!BUF_MEM_grow(s->init_buf, 8 + s->tlsext_ocsp_resplen))
			return -1;

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

		/* do the header */
		*(p++)=SSL3_MT_CERTIFICATE_STATUS;
		/* message length */
		l2n3(s->tlsext_ocsp_resplen + 4, p);
		/* status type */
		*(p++)= s->tlsext_status_type;
		/* length of OCSP response */
		l2n3(s->tlsext_ocsp_resplen, p);
		/* actual response */
		memcpy(p, s->tlsext_ocsp_resp, s->tlsext_ocsp_resplen);
		/* number of bytes to write */
		s->init_num = 8 + s->tlsext_ocsp_resplen;
		s->state=SSL3_ST_SW_CERT_STATUS_B;
		s->init_off = 0;
		}

	/* SSL3_ST_SW_CERT_STATUS_B */
	return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
	}
#endif

/* 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((int)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)
		return 0;

	if (!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((int)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;
	}

