/* ssl/s3_clnt.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 * 
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 * 
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from 
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 * 
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * 
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */
/* ====================================================================
 * Copyright (c) 1998-2007 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    openssl-core@openssl.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */
/* ====================================================================
 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
 *
 * Portions of the attached software ("Contribution") are developed by 
 * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
 *
 * The Contribution is licensed pursuant to the OpenSSL open source
 * license provided above.
 *
 * ECC cipher suite support in OpenSSL originally written by
 * Vipul Gupta and Sumit Gupta of Sun Microsystems Laboratories.
 *
 */
/* ====================================================================
 * Copyright 2005 Nokia. All rights reserved.
 *
 * The portions of the attached software ("Contribution") is developed by
 * Nokia Corporation and is licensed pursuant to the OpenSSL open source
 * license.
 *
 * The Contribution, originally written by Mika Kousa and Pasi Eronen of
 * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
 * support (see RFC 4279) to OpenSSL.
 *
 * No patent licenses or other rights except those expressly stated in
 * the OpenSSL open source license shall be deemed granted or received
 * expressly, by implication, estoppel, or otherwise.
 *
 * No assurances are provided by Nokia that the Contribution does not
 * infringe the patent or other intellectual property rights of any third
 * party or that the license provides you with all the necessary rights
 * to make use of the Contribution.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
 * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
 * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
 * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
 * OTHERWISE.
 */

#include <stdio.h>

#include <openssl/buf.h>
#include <openssl/bytestring.h>
#include <openssl/rand.h>
#include <openssl/obj.h>
#include <openssl/evp.h>
#include <openssl/mem.h>
#include <openssl/md5.h>
#include <openssl/dh.h>
#include <openssl/bn.h>
#include <openssl/engine.h>
#include <openssl/x509.h>

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

static const SSL_METHOD *ssl3_get_client_method(int ver);

static const SSL_METHOD *ssl3_get_client_method(int ver)
	{
	if (ver == SSL3_VERSION)
		return(SSLv3_client_method());
	else
		return(NULL);
	}

IMPLEMENT_ssl3_meth_func(SSLv3_client_method,
			ssl_undefined_function,
			ssl3_connect,
			ssl3_get_client_method)

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

	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 (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s); 

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

		switch(s->state)
			{
		case SSL_ST_RENEGOTIATE:
			s->renegotiate=1;
			s->state=SSL_ST_CONNECT;
			s->ctx->stats.sess_connect_renegotiate++;
			/* break */
		case SSL_ST_BEFORE:
		case SSL_ST_CONNECT:
		case SSL_ST_BEFORE|SSL_ST_CONNECT:
		case SSL_ST_OK|SSL_ST_CONNECT:

			s->server=0;
			if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_START,1);

			if ((s->version & 0xff00 ) != 0x0300)
				{
				OPENSSL_PUT_ERROR(SSL, ssl3_connect, ERR_R_INTERNAL_ERROR);
				ret = -1;
				goto end;
				}
				
			/* s->version=SSL3_VERSION; */
			s->type=SSL_ST_CONNECT;

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

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

			/* setup buffing BIO */
			if (!ssl_init_wbio_buffer(s,0)) { ret= -1; goto end; }

			/* don't push the buffering BIO quite yet */

			ssl3_init_finished_mac(s);

			s->state=SSL3_ST_CW_CLNT_HELLO_A;
			s->ctx->stats.sess_connect++;
			s->init_num=0;
			break;

		case SSL3_ST_CW_CLNT_HELLO_A:
		case SSL3_ST_CW_CLNT_HELLO_B:

			s->shutdown=0;
			ret=ssl3_client_hello(s);
			if (ret <= 0) goto end;
			s->state=SSL3_ST_CR_SRVR_HELLO_A;
			s->init_num=0;

			/* turn on buffering for the next lot of output */
			if (s->bbio != s->wbio)
				s->wbio=BIO_push(s->bbio,s->wbio);

			break;

		case SSL3_ST_CR_SRVR_HELLO_A:
		case SSL3_ST_CR_SRVR_HELLO_B:
			ret=ssl3_get_server_hello(s);
			if (ret <= 0) goto end;

			if (s->hit)
				{
				s->state=SSL3_ST_CR_FINISHED_A;
				if (s->tlsext_ticket_expected)
					{
					/* receive renewed session ticket */
					s->state=SSL3_ST_CR_SESSION_TICKET_A;
					}
				}
			else
				{
				s->state=SSL3_ST_CR_CERT_A;
				}
			s->init_num=0;
			break;

		case SSL3_ST_CR_CERT_A:
		case SSL3_ST_CR_CERT_B:
			if (ssl_cipher_has_server_public_key(s->s3->tmp.new_cipher))
				{
				ret=ssl3_get_server_certificate(s);
				if (ret <= 0) goto end;
				if (s->tlsext_status_expected)
					s->state=SSL3_ST_CR_CERT_STATUS_A;
				else
					s->state=SSL3_ST_CR_KEY_EXCH_A;
				}
			else
				{
				skip = 1;
				s->state=SSL3_ST_CR_KEY_EXCH_A;
				}
			s->init_num=0;
			break;

		case SSL3_ST_CR_KEY_EXCH_A:
		case SSL3_ST_CR_KEY_EXCH_B:
			ret=ssl3_get_server_key_exchange(s);
			if (ret <= 0) goto end;
			s->state=SSL3_ST_CR_CERT_REQ_A;
			s->init_num=0;

			/* at this point we check that we have the
			 * required stuff from the server */
			if (!ssl3_check_cert_and_algorithm(s))
				{
				ret= -1;
				goto end;
				}
			break;

		case SSL3_ST_CR_CERT_REQ_A:
		case SSL3_ST_CR_CERT_REQ_B:
			ret=ssl3_get_certificate_request(s);
			if (ret <= 0) goto end;
			s->state=SSL3_ST_CR_SRVR_DONE_A;
			s->init_num=0;
			break;

		case SSL3_ST_CR_SRVR_DONE_A:
		case SSL3_ST_CR_SRVR_DONE_B:
			ret=ssl3_get_server_done(s);
			if (ret <= 0) goto end;
			if (s->s3->tmp.cert_req)
				s->state=SSL3_ST_CW_CERT_A;
			else
				s->state=SSL3_ST_CW_KEY_EXCH_A;
			s->init_num=0;

			break;

		case SSL3_ST_CW_CERT_A:
		case SSL3_ST_CW_CERT_B:
		case SSL3_ST_CW_CERT_C:
		case SSL3_ST_CW_CERT_D:
			ret=ssl3_send_client_certificate(s);
			if (ret <= 0) goto end;
			s->state=SSL3_ST_CW_KEY_EXCH_A;
			s->init_num=0;
			break;

		case SSL3_ST_CW_KEY_EXCH_A:
		case SSL3_ST_CW_KEY_EXCH_B:
			ret=ssl3_send_client_key_exchange(s);
			if (ret <= 0) goto end;
			/* EAY EAY EAY need to check for DH fix cert
			 * sent back */
			/* For TLS, cert_req is set to 2, so a cert chain
			 * of nothing is sent, but no verify packet is sent */
			/* XXX: For now, we do not support client 
			 * authentication in ECDH cipher suites with
			 * ECDH (rather than ECDSA) certificates.
			 * We need to skip the certificate verify 
			 * message when client's ECDH public key is sent 
			 * inside the client certificate.
			 */
			if (s->s3->tmp.cert_req == 1)
				{
				s->state=SSL3_ST_CW_CERT_VRFY_A;
				}
			else
				{
				s->state=SSL3_ST_CW_CHANGE_A;
				s->s3->change_cipher_spec=0;
				}
			if (s->s3->flags & TLS1_FLAGS_SKIP_CERT_VERIFY)
				{
				s->state=SSL3_ST_CW_CHANGE_A;
				s->s3->change_cipher_spec=0;
				}

			s->init_num=0;
			break;

		case SSL3_ST_CW_CERT_VRFY_A:
		case SSL3_ST_CW_CERT_VRFY_B:
			ret=ssl3_send_client_verify(s);
			if (ret <= 0) goto end;
			s->state=SSL3_ST_CW_CHANGE_A;
			s->init_num=0;
			s->s3->change_cipher_spec=0;
			break;

		case SSL3_ST_CW_CHANGE_A:
		case SSL3_ST_CW_CHANGE_B:
			ret=ssl3_send_change_cipher_spec(s,
				SSL3_ST_CW_CHANGE_A,SSL3_ST_CW_CHANGE_B);
			if (ret <= 0) goto end;

 			s->state=SSL3_ST_CW_FINISHED_A;
			if (s->s3->tlsext_channel_id_valid)
				s->state=SSL3_ST_CW_CHANNEL_ID_A;
# if !defined(OPENSSL_NO_NEXTPROTONEG)
			if (s->s3->next_proto_neg_seen)
				s->state=SSL3_ST_CW_NEXT_PROTO_A;
# endif
			s->init_num=0;

			s->session->cipher=s->s3->tmp.new_cipher;
			if (!s->method->ssl3_enc->setup_key_block(s))
				{
				ret= -1;
				goto end;
				}

			if (!s->method->ssl3_enc->change_cipher_state(s,
				SSL3_CHANGE_CIPHER_CLIENT_WRITE))
				{
				ret= -1;
				goto end;
				}

			break;

#if !defined(OPENSSL_NO_NEXTPROTONEG)
		case SSL3_ST_CW_NEXT_PROTO_A:
		case SSL3_ST_CW_NEXT_PROTO_B:
			ret=ssl3_send_next_proto(s);
			if (ret <= 0) goto end;
			if (s->s3->tlsext_channel_id_valid)
				s->state=SSL3_ST_CW_CHANNEL_ID_A;
			else
				s->state=SSL3_ST_CW_FINISHED_A;
			break;
#endif

		case SSL3_ST_CW_CHANNEL_ID_A:
		case SSL3_ST_CW_CHANNEL_ID_B:
			ret=ssl3_send_channel_id(s);
			if (ret <= 0) goto end;
			s->state=SSL3_ST_CW_FINISHED_A;
			break;

		case SSL3_ST_CW_FINISHED_A:
		case SSL3_ST_CW_FINISHED_B:
			ret=ssl3_send_finished(s,
				SSL3_ST_CW_FINISHED_A,SSL3_ST_CW_FINISHED_B,
				s->method->ssl3_enc->client_finished_label,
				s->method->ssl3_enc->client_finished_label_len);
			if (ret <= 0) goto end;
			s->s3->flags |= SSL3_FLAGS_CCS_OK;
			s->state=SSL3_ST_CW_FLUSH;

			/* clear flags */
			s->s3->flags&= ~SSL3_FLAGS_POP_BUFFER;
			if (s->hit)
				{
				s->s3->tmp.next_state=SSL_ST_OK;
				}
			else
				{
				/* This is a non-resumption handshake. If it
				 * involves ChannelID, then record the
				 * handshake hashes at this point in the
				 * session so that any resumption of this
				 * session with ChannelID can sign those
				 * hashes. */
				if (s->s3->tlsext_channel_id_new)
					{
					ret = tls1_record_handshake_hashes_for_channel_id(s);
					if (ret <= 0)
						goto end;
					}
				if ((SSL_get_mode(s) & SSL_MODE_HANDSHAKE_CUTTHROUGH)
				    && ssl3_can_cutthrough(s)
				    && s->s3->previous_server_finished_len == 0 /* no cutthrough on renegotiation (would complicate the state machine) */
				   )
					{
					s->s3->tmp.next_state=SSL3_ST_CUTTHROUGH_COMPLETE;
					}
				else
					{
					/* Allow NewSessionTicket if ticket expected */
					if (s->tlsext_ticket_expected)
						s->s3->tmp.next_state=SSL3_ST_CR_SESSION_TICKET_A;
					else
						s->s3->tmp.next_state=SSL3_ST_CR_FINISHED_A;
					}
				}
			s->init_num=0;
			break;

		case SSL3_ST_CR_SESSION_TICKET_A:
		case SSL3_ST_CR_SESSION_TICKET_B:
			ret=ssl3_get_new_session_ticket(s);
			if (ret <= 0) goto end;
			s->state=SSL3_ST_CR_FINISHED_A;
			s->init_num=0;
		break;

		case SSL3_ST_CR_CERT_STATUS_A:
		case SSL3_ST_CR_CERT_STATUS_B:
			ret=ssl3_get_cert_status(s);
			if (ret <= 0) goto end;
			s->state=SSL3_ST_CR_KEY_EXCH_A;
			s->init_num=0;
		break;

		case SSL3_ST_CR_FINISHED_A:
		case SSL3_ST_CR_FINISHED_B:

			s->s3->flags |= SSL3_FLAGS_CCS_OK;
			ret=ssl3_get_finished(s,SSL3_ST_CR_FINISHED_A,
				SSL3_ST_CR_FINISHED_B);
			if (ret <= 0) goto end;

			if (s->hit)
				s->state=SSL3_ST_CW_CHANGE_A;
			else
				s->state=SSL_ST_OK;
			s->init_num=0;
			break;

		case SSL3_ST_CW_FLUSH:
			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_CUTTHROUGH_COMPLETE:
			/* Allow NewSessionTicket if ticket expected */
			if (s->tlsext_ticket_expected)
				s->state=SSL3_ST_CR_SESSION_TICKET_A;
			else
				s->state=SSL3_ST_CR_FINISHED_A;

			ssl_free_wbio_buffer(s);
			ret = 1;
			goto end;
			/* break; */

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

			if (s->init_buf != NULL)
				{
				BUF_MEM_free(s->init_buf);
				s->init_buf=NULL;
				}

			/* If we are not 'joining' the last two packets,
			 * remove the buffering now */
			if (!(s->s3->flags & SSL3_FLAGS_POP_BUFFER))
				ssl_free_wbio_buffer(s);
			/* else do it later in ssl3_write */

			s->init_num=0;
			s->renegotiate=0;
			s->new_session=0;

			ssl_update_cache(s,SSL_SESS_CACHE_CLIENT);
			if (s->hit) s->ctx->stats.sess_hit++;

			ret=1;
			/* s->server=0; */
			s->handshake_func=ssl3_connect;
			s->ctx->stats.sess_connect_good++;

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

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

		/* did we do anything */
		if (!s->s3->tmp.reuse_message && !skip)
			{
			if (s->debug)
				{
				if ((ret=BIO_flush(s->wbio)) <= 0)
					goto end;
				}

			if ((cb != NULL) && (s->state != state))
				{
				new_state=s->state;
				s->state=state;
				cb(s,SSL_CB_CONNECT_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_CONNECT_EXIT,ret);
	return(ret);
	}


int ssl3_client_hello(SSL *s)
	{
	unsigned char *buf;
	unsigned char *p,*d;
	int i;
	unsigned long l;

	buf=(unsigned char *)s->init_buf->data;
	if (s->state == SSL3_ST_CW_CLNT_HELLO_A)
		{
		SSL_SESSION *sess = s->session;
		if (sess == NULL ||
			sess->ssl_version != s->version ||
			!sess->session_id_length ||
			sess->not_resumable)
			{
			if (!ssl_get_new_session(s,0))
				goto err;
			}
		if (s->method->version == DTLS_ANY_VERSION)
			{
			/* Determine which DTLS version to use */
			int options = s->options;
			/* If DTLS 1.2 disabled correct the version number */
			if (options & SSL_OP_NO_DTLSv1_2)
				{
				if (tls1_suiteb(s))
					{
					OPENSSL_PUT_ERROR(SSL, ssl3_client_hello, SSL_R_ONLY_DTLS_1_2_ALLOWED_IN_SUITEB_MODE);
					goto err;
					}
				/* Disabling all versions is silly: return an
				 * error.
				 */
				if (options & SSL_OP_NO_DTLSv1)
					{
					OPENSSL_PUT_ERROR(SSL, ssl3_client_hello, SSL_R_WRONG_SSL_VERSION);
					goto err;
					}
				/* Update method so we don't use any DTLS 1.2
				 * features.
				 */
				s->method = DTLSv1_client_method();
				s->version = DTLS1_VERSION;
				}
			else
				{
				/* We only support one version: update method */
				if (options & SSL_OP_NO_DTLSv1)
					s->method = DTLSv1_2_client_method();
				s->version = DTLS1_2_VERSION;
				}
			s->client_version = s->version;
			}
		/* else use the pre-loaded session */

		p=s->s3->client_random;

		/* for DTLS if client_random is initialized, reuse it, we are
		 * required to use same upon reply to HelloVerify */
		if (SSL_IS_DTLS(s))
			{
			size_t idx;
			i = 1;
			for (idx=0; idx < sizeof(s->s3->client_random); idx++)
				{
				if (p[idx])
					{
					i = 0;
					break;
					}
				}
			}
		else 
			i = 1;

		if (i)
			ssl_fill_hello_random(s, 0, p,
					      sizeof(s->s3->client_random));

		/* Do the message type and length last.
		 * Note: the final argument to ssl_add_clienthello_tlsext below
		 * depends on the size of this prefix. */
		d=p= ssl_handshake_start(s);

		/* version indicates the negotiated version: for example from
		 * an SSLv2/v3 compatible client hello). The client_version
		 * field is the maximum version we permit and it is also
		 * used in RSA encrypted premaster secrets. Some servers can
		 * choke if we initially report a higher version then
		 * renegotiate to a lower one in the premaster secret. This
		 * didn't happen with TLS 1.0 as most servers supported it
		 * but it can with TLS 1.1 or later if the server only supports
		 * 1.0.
		 *
		 * Possible scenario with previous logic:
		 * 	1. Client hello indicates TLS 1.2
		 * 	2. Server hello says TLS 1.0
		 *	3. RSA encrypted premaster secret uses 1.2.
		 * 	4. Handhaked proceeds using TLS 1.0.
		 *	5. Server sends hello request to renegotiate.
		 *	6. Client hello indicates TLS v1.0 as we now
		 *	   know that is maximum server supports.
		 *	7. Server chokes on RSA encrypted premaster secret
		 *	   containing version 1.0.
		 *
		 * For interoperability it should be OK to always use the
		 * maximum version we support in client hello and then rely
		 * on the checking of version to ensure the servers isn't
		 * being inconsistent: for example initially negotiating with
		 * TLS 1.0 and renegotiating with TLS 1.2. We do this by using
		 * client_version in client hello and not resetting it to
		 * the negotiated version.
		 */
#if 0
		*(p++)=s->version>>8;
		*(p++)=s->version&0xff;
		s->client_version=s->version;
#else
		*(p++)=s->client_version>>8;
		*(p++)=s->client_version&0xff;
#endif

		/* Random stuff */
		memcpy(p,s->s3->client_random,SSL3_RANDOM_SIZE);
		p+=SSL3_RANDOM_SIZE;

		/* Session ID */
		if (s->new_session)
			i=0;
		else
			i=s->session->session_id_length;
		*(p++)=i;
		if (i != 0)
			{
			if (i > (int)sizeof(s->session->session_id))
				{
				OPENSSL_PUT_ERROR(SSL, ssl3_client_hello, ERR_R_INTERNAL_ERROR);
				goto err;
				}
			memcpy(p,s->session->session_id,i);
			p+=i;
			}
		
		/* cookie stuff for DTLS */
		if (SSL_IS_DTLS(s))
			{
			if ( s->d1->cookie_len > sizeof(s->d1->cookie))
				{
				OPENSSL_PUT_ERROR(SSL, ssl3_client_hello, ERR_R_INTERNAL_ERROR);
				goto err;
				}
			*(p++) = s->d1->cookie_len;
			memcpy(p, s->d1->cookie, s->d1->cookie_len);
			p += s->d1->cookie_len;
			}
		
		/* Ciphers supported */
		i=ssl_cipher_list_to_bytes(s,SSL_get_ciphers(s),&(p[2]),0);
		if (i == 0)
			{
			OPENSSL_PUT_ERROR(SSL, ssl3_client_hello, SSL_R_NO_CIPHERS_AVAILABLE);
			goto err;
			}
#ifdef OPENSSL_MAX_TLS1_2_CIPHER_LENGTH
			/* Some servers hang if client hello > 256 bytes
			 * as hack workaround chop number of supported ciphers
			 * to keep it well below this if we use TLS v1.2
			 */
			if (TLS1_get_version(s) >= TLS1_2_VERSION
				&& i > OPENSSL_MAX_TLS1_2_CIPHER_LENGTH)
				i = OPENSSL_MAX_TLS1_2_CIPHER_LENGTH & ~1;
#endif
		s2n(i,p);
		p+=i;

		/* COMPRESSION */
		*(p++)=1;
		*(p++)=0; /* Add the NULL method */

		/* TLS extensions*/
		if (ssl_prepare_clienthello_tlsext(s) <= 0)
			{
			OPENSSL_PUT_ERROR(SSL, ssl3_client_hello, SSL_R_CLIENTHELLO_TLSEXT);
			goto err;
			}
		if ((p = ssl_add_clienthello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH, p-buf)) == NULL)
			{
			OPENSSL_PUT_ERROR(SSL, ssl3_client_hello, ERR_R_INTERNAL_ERROR);
			goto err;
			}
		
		l= p-d;
		ssl_set_handshake_header(s, SSL3_MT_CLIENT_HELLO, l);
		s->state=SSL3_ST_CW_CLNT_HELLO_B;
		}

	/* SSL3_ST_CW_CLNT_HELLO_B */
	return ssl_do_write(s);
err:
	return(-1);
	}

int ssl3_get_server_hello(SSL *s)
	{
	STACK_OF(SSL_CIPHER) *sk;
	const SSL_CIPHER *c;
	CERT *ct = s->cert;
	int al=SSL_AD_INTERNAL_ERROR,ok;
	long n;
	CBS server_hello, server_random, session_id;
	uint16_t server_version;
	const uint8_t *cipher_ptr;
	uint8_t compression_method;
	/* Hello verify request and/or server hello version may not
	 * match so set first packet if we're negotiating version.
	 */
	if (SSL_IS_DTLS(s))
		s->first_packet = 1;

	n=s->method->ssl_get_message(s,
		SSL3_ST_CR_SRVR_HELLO_A,
		SSL3_ST_CR_SRVR_HELLO_B,
		-1,
		20000, /* ?? */
		&ok);

	if (!ok) return((int)n);

	if (SSL_IS_DTLS(s))
		{
		s->first_packet = 0;
		if ( s->s3->tmp.message_type == DTLS1_MT_HELLO_VERIFY_REQUEST)
			{
			if ( s->d1->send_cookie == 0)
				{
				s->s3->tmp.reuse_message = 1;
				return 1;
				}
			else /* already sent a cookie */
				{
				al=SSL_AD_UNEXPECTED_MESSAGE;
				OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello, SSL_R_BAD_MESSAGE_TYPE);
				goto f_err;
				}
			}
		}
	
	if ( s->s3->tmp.message_type != SSL3_MT_SERVER_HELLO)
		{
		al=SSL_AD_UNEXPECTED_MESSAGE;
		OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello, SSL_R_BAD_MESSAGE_TYPE);
		goto f_err;
		}

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

	if (!CBS_get_u16(&server_hello, &server_version) ||
		!CBS_get_bytes(&server_hello, &server_random, SSL3_RANDOM_SIZE) ||
		!CBS_get_u8_length_prefixed(&server_hello, &session_id) ||
		CBS_len(&session_id) > SSL3_SESSION_ID_SIZE)
		{
		al = SSL_AD_DECODE_ERROR;
		OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello, SSL_R_DECODE_ERROR);
		goto f_err;
		}

	if (s->method->version == DTLS_ANY_VERSION)
		{
		/* Work out correct protocol version to use */
		int options = s->options;
		if (server_version == DTLS1_2_VERSION
			&& !(options & SSL_OP_NO_DTLSv1_2))
			s->method = DTLSv1_2_client_method();
		else if (tls1_suiteb(s))
			{
			OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello, SSL_R_ONLY_DTLS_1_2_ALLOWED_IN_SUITEB_MODE);
			s->version = server_version;
			al = SSL_AD_PROTOCOL_VERSION;
			goto f_err;
			}
		else if (server_version == DTLS1_VERSION
			&& !(options & SSL_OP_NO_DTLSv1))
			s->method = DTLSv1_client_method();
		else
			{
			OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello, SSL_R_WRONG_SSL_VERSION);
			s->version = server_version;
			al = SSL_AD_PROTOCOL_VERSION;
			goto f_err;
			}
		s->version = s->client_version = s->method->version;
		}

	if (server_version != s->version)
		{
		OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello, SSL_R_WRONG_SSL_VERSION);
		s->version = (s->version & 0xff00) | (server_version & 0xff);
		al = SSL_AD_PROTOCOL_VERSION;
		goto f_err;
		}

	/* Copy over the server random. */
	memcpy(s->s3->server_random, CBS_data(&server_random), SSL3_RANDOM_SIZE);

	s->hit = 0;

	/* check if we want to resume the session based on external pre-shared secret */
	if (s->version >= TLS1_VERSION && s->tls_session_secret_cb)
		{
		SSL_CIPHER *pref_cipher=NULL;
		s->session->master_key_length=sizeof(s->session->master_key);
		if (s->tls_session_secret_cb(s, s->session->master_key,
					     &s->session->master_key_length,
					     NULL, &pref_cipher,
					     s->tls_session_secret_cb_arg))
			{
			/* TODO(davidben): Make ssl_get_cipher_by_char
			 * a bounds-checked function. */
			s->session->cipher = pref_cipher ?
				pref_cipher :
				ssl_get_cipher_by_char(s, CBS_data(&server_hello));
	    		s->s3->flags |= SSL3_FLAGS_CCS_OK;
			s->hit = 1;
			}
		}

	if (!s->hit && CBS_len(&session_id) != 0 &&
		CBS_mem_equal(&session_id,
			s->session->session_id, s->session->session_id_length))
		{
		if(s->sid_ctx_length != s->session->sid_ctx_length
			|| memcmp(s->session->sid_ctx, s->sid_ctx, s->sid_ctx_length))
			{
			/* actually a client application bug */
			al = SSL_AD_ILLEGAL_PARAMETER;
			OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello, SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT);
			goto f_err;
			}
		s->s3->flags |= SSL3_FLAGS_CCS_OK;
		s->hit = 1;
		}

	/* a miss or crap from the other end */
	if (!s->hit)
		{
		/* If we were trying for session-id reuse, make a new
		 * SSL_SESSION so we don't stuff up other people */
		if (s->session->session_id_length > 0)
			{
			if (!ssl_get_new_session(s,0))
				{
				goto f_err;
				}
			}
		/* Note: session_id could be empty. */
		s->session->session_id_length = CBS_len(&session_id);
		memcpy(s->session->session_id, CBS_data(&session_id), CBS_len(&session_id));
		}

	/* TODO(davidben): Move the cipher_by_char hooks to CBS or
	 * something else actually bounds-checked. */
	cipher_ptr = CBS_data(&server_hello);
	if (!CBS_skip(&server_hello, 2))
		{
		al = SSL_AD_DECODE_ERROR;
		OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello, SSL_R_DECODE_ERROR);
		goto f_err;
		}
	c = ssl_get_cipher_by_char(s, cipher_ptr);
	if (c == NULL)
		{
		/* unknown cipher */
		al = SSL_AD_ILLEGAL_PARAMETER;
		OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello, SSL_R_UNKNOWN_CIPHER_RETURNED);
		goto f_err;
		}
	/* If it is a disabled cipher we didn't send it in client hello,
	 * so return an error.
	 */
	if (c->algorithm_ssl & ct->mask_ssl ||
		c->algorithm_mkey & ct->mask_k ||
		c->algorithm_auth & ct->mask_a)
		{
		al=SSL_AD_ILLEGAL_PARAMETER;
		OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello, SSL_R_WRONG_CIPHER_RETURNED);
		goto f_err;
		}

	sk=ssl_get_ciphers_by_id(s);
	if (!sk_SSL_CIPHER_find(sk, NULL, c))
		{
		/* we did not say we would use this cipher */
		al=SSL_AD_ILLEGAL_PARAMETER;
		OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello, SSL_R_WRONG_CIPHER_RETURNED);
		goto f_err;
		}

	/* Depending on the session caching (internal/external), the cipher
	   and/or cipher_id values may not be set. Make sure that
	   cipher_id is set and use it for comparison. */
	if (s->session->cipher)
		s->session->cipher_id = s->session->cipher->id;
	if (s->hit && (s->session->cipher_id != c->id))
		{
		al = SSL_AD_ILLEGAL_PARAMETER;
		OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello, SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED);
		goto f_err;
		}
	s->s3->tmp.new_cipher=c;
	/* Don't digest cached records if no sigalgs: we may need them for
	 * client authentication.
	 */
	if (!SSL_USE_SIGALGS(s) && !ssl3_digest_cached_records(s))
		goto f_err;

	if (!CBS_get_u8(&server_hello, &compression_method))
		{
		al = SSL_AD_DECODE_ERROR;
		OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello, SSL_R_DECODE_ERROR);
		}

	/* Only the NULL compression algorithm is supported. */
	if (compression_method != 0)
		{
		al = SSL_AD_ILLEGAL_PARAMETER;
		OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello, SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM);
		goto f_err;
		}

	/* TLS extensions */
	if (!ssl_parse_serverhello_tlsext(s, &server_hello))
		{
		OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello, SSL_R_PARSE_TLSEXT);
		goto err; 
		}

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

	return(1);
f_err:
	ssl3_send_alert(s,SSL3_AL_FATAL,al);
err:
	return(-1);
	}

int ssl3_get_server_certificate(SSL *s)
	{
	int al,i,ok,ret= -1;
	unsigned long n;
	X509 *x=NULL;
	STACK_OF(X509) *sk=NULL;
	SESS_CERT *sc;
	EVP_PKEY *pkey=NULL;
	CBS cbs, certificate_list;
	const uint8_t* data;

	n=s->method->ssl_get_message(s,
		SSL3_ST_CR_CERT_A,
		SSL3_ST_CR_CERT_B,
		SSL3_MT_CERTIFICATE,
		s->max_cert_list,
		&ok);

	if (!ok) return((int)n);

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

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

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

	while (CBS_len(&certificate_list) > 0)
		{
		CBS certificate;
		if (!CBS_get_u24_length_prefixed(&certificate_list, &certificate))
			{
			al = SSL_AD_DECODE_ERROR;
			OPENSSL_PUT_ERROR(SSL, ssl3_get_server_certificate, SSL_R_CERT_LENGTH_MISMATCH);
			goto f_err;
			}
		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_server_certificate, ERR_R_ASN1_LIB);
			goto f_err;
			}
		if (!CBS_skip(&certificate, data - CBS_data(&certificate)))
			{
			al = SSL_AD_INTERNAL_ERROR;
			OPENSSL_PUT_ERROR(SSL, ssl3_get_server_certificate, ERR_R_INTERNAL_ERROR);
			goto f_err;
			}
		if (CBS_len(&certificate) != 0)
			{
			al = SSL_AD_DECODE_ERROR;
			OPENSSL_PUT_ERROR(SSL, ssl3_get_server_certificate, SSL_R_CERT_LENGTH_MISMATCH);
			goto f_err;
			}
		if (!sk_X509_push(sk,x))
			{
			OPENSSL_PUT_ERROR(SSL, ssl3_get_server_certificate, ERR_R_MALLOC_FAILURE);
			goto err;
			}
		x=NULL;
		}

	i=ssl_verify_cert_chain(s,sk);
	if ((s->verify_mode != SSL_VERIFY_NONE) && (i <= 0)
		)
		{
		al=ssl_verify_alarm_type(s->verify_result);
		OPENSSL_PUT_ERROR(SSL, ssl3_get_server_certificate, SSL_R_CERTIFICATE_VERIFY_FAILED);
		goto f_err; 
		}
	ERR_clear_error(); /* but we keep s->verify_result */

	sc=ssl_sess_cert_new();
	if (sc == NULL) goto err;

	if (s->session->sess_cert) ssl_sess_cert_free(s->session->sess_cert);
	s->session->sess_cert=sc;

	sc->cert_chain=sk;
	/* Inconsistency alert: cert_chain does include the peer's
	 * certificate, which we don't include in s3_srvr.c */
	x=sk_X509_value(sk,0);
	sk=NULL;
 	/* VRS 19990621: possible memory leak; sk=null ==> !sk_pop_free() @end*/

	pkey=X509_get_pubkey(x);

	if ((pkey == NULL) || EVP_PKEY_missing_parameters(pkey))
		{
		x=NULL;
		al=SSL3_AL_FATAL;
		OPENSSL_PUT_ERROR(SSL, ssl3_get_server_certificate, SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS);
		goto f_err;
		}

	i=ssl_cert_type(x,pkey);
	if (i < 0)
		{
		x=NULL;
		al=SSL3_AL_FATAL;
		OPENSSL_PUT_ERROR(SSL, ssl3_get_server_certificate, SSL_R_UNKNOWN_CERTIFICATE_TYPE);
		goto f_err;
		}

	int exp_idx = ssl_cipher_get_cert_index(s->s3->tmp.new_cipher);
	if (exp_idx >= 0 && i != exp_idx)
		{
		x=NULL;
		al=SSL_AD_ILLEGAL_PARAMETER;
		OPENSSL_PUT_ERROR(SSL, ssl3_get_server_certificate, SSL_R_WRONG_CERTIFICATE_TYPE);
		goto f_err;
		}
	sc->peer_cert_type=i;
	CRYPTO_add(&x->references,1,CRYPTO_LOCK_X509);
	/* Why would the following ever happen?
	 * We just created sc a couple of lines ago. */
	if (sc->peer_pkeys[i].x509 != NULL)
		X509_free(sc->peer_pkeys[i].x509);
	sc->peer_pkeys[i].x509=x;
	sc->peer_key= &(sc->peer_pkeys[i]);

	if (s->session->peer != NULL)
		X509_free(s->session->peer);
	CRYPTO_add(&x->references,1,CRYPTO_LOCK_X509);
	s->session->peer=x;

	s->session->verify_result = s->verify_result;

	x=NULL;
	ret=1;
	if (0)
		{
f_err:
		ssl3_send_alert(s,SSL3_AL_FATAL,al);
		}
err:
	EVP_PKEY_free(pkey);
	X509_free(x);
	sk_X509_pop_free(sk,X509_free);
	return(ret);
	}

int ssl3_get_server_key_exchange(SSL *s)
	{
	EVP_MD_CTX md_ctx;
	int al,ok;
	long n,alg_k,alg_a;
	EVP_PKEY *pkey=NULL;
	const EVP_MD *md = NULL;
	RSA *rsa=NULL;
#ifndef OPENSSL_NO_DH
	DH *dh=NULL;
#endif
#ifndef OPENSSL_NO_ECDH
	EC_KEY *ecdh = NULL;
	BN_CTX *bn_ctx = NULL;
	EC_POINT *srvr_ecpoint = NULL;
#endif
	CBS server_key_exchange, server_key_exchange_orig, parameter;

	/* use same message size as in ssl3_get_certificate_request()
	 * as ServerKeyExchange message may be skipped */
	n=s->method->ssl_get_message(s,
		SSL3_ST_CR_KEY_EXCH_A,
		SSL3_ST_CR_KEY_EXCH_B,
		-1,
		s->max_cert_list,
		&ok);
	if (!ok) return((int)n);

	if (s->s3->tmp.message_type != SSL3_MT_SERVER_KEY_EXCHANGE)
		{
		if (ssl_cipher_requires_server_key_exchange(s->s3->tmp.new_cipher))
			{
			OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, SSL_R_UNEXPECTED_MESSAGE);
			ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
			return -1;
			}

#ifndef OPENSSL_NO_PSK
		/* In plain PSK ciphersuite, ServerKeyExchange can be
		   omitted if no identity hint is sent. Set
		   session->sess_cert anyway to avoid problems
		   later.*/
		if (s->s3->tmp.new_cipher->algorithm_auth & SSL_aPSK)
			{
			/* PSK ciphersuites that also send a
			 * Certificate would have already initialized
			 * |sess_cert|. */
			if (s->session->sess_cert == NULL)
				s->session->sess_cert = ssl_sess_cert_new();
			if (s->session->psk_identity_hint)
				{
				OPENSSL_free(s->session->psk_identity_hint);
				s->session->psk_identity_hint = NULL;
				}
			}
#endif
		s->s3->tmp.reuse_message=1;
		return(1);
		}

	/* Retain a copy of the original CBS to compute the signature
	 * over. */
	CBS_init(&server_key_exchange, s->init_msg, n);
	server_key_exchange_orig = server_key_exchange;

	if (s->session->sess_cert != NULL)
		{
		if (s->session->sess_cert->peer_rsa_tmp != NULL)
			{
			RSA_free(s->session->sess_cert->peer_rsa_tmp);
			s->session->sess_cert->peer_rsa_tmp=NULL;
			}
#ifndef OPENSSL_NO_DH
		if (s->session->sess_cert->peer_dh_tmp)
			{
			DH_free(s->session->sess_cert->peer_dh_tmp);
			s->session->sess_cert->peer_dh_tmp=NULL;
			}
#endif
#ifndef OPENSSL_NO_ECDH
		if (s->session->sess_cert->peer_ecdh_tmp)
			{
			EC_KEY_free(s->session->sess_cert->peer_ecdh_tmp);
			s->session->sess_cert->peer_ecdh_tmp=NULL;
			}
#endif
		}
	else
		{
		s->session->sess_cert=ssl_sess_cert_new();
		}

	alg_k=s->s3->tmp.new_cipher->algorithm_mkey;
	alg_a=s->s3->tmp.new_cipher->algorithm_auth;
	EVP_MD_CTX_init(&md_ctx);

#ifndef OPENSSL_NO_PSK
	if (alg_a & SSL_aPSK)
		{
		CBS psk_identity_hint;

		/* Each of the PSK key exchanges begins with a
		 * psk_identity_hint. */
		if (!CBS_get_u16_length_prefixed(&server_key_exchange, &psk_identity_hint))
			{
			al = SSL_AD_DECODE_ERROR;
			OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, SSL_R_DECODE_ERROR);
			goto f_err;
			}

		/* Store PSK identity hint for later use, hint is used in
		 * ssl3_send_client_key_exchange.  Assume that the maximum
		 * length of a PSK identity hint can be as long as the maximum
		 * length of a PSK identity. Also do not allow NULL
		 * characters; identities are saved as C strings.
		 *
		 * TODO(davidben): Should invalid hints be ignored? It's a hint
		 * rather than a specific identity. */
		if (CBS_len(&psk_identity_hint) > PSK_MAX_IDENTITY_LEN ||
			CBS_contains_zero_byte(&psk_identity_hint))
			{
			al = SSL_AD_HANDSHAKE_FAILURE;
			OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, SSL_R_DATA_LENGTH_TOO_LONG);
			goto f_err;
			}

		/* Save the identity hint as a C string. */
		if (!CBS_strdup(&psk_identity_hint, &s->session->psk_identity_hint))
			{
			al = SSL_AD_HANDSHAKE_FAILURE;
			OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, ERR_R_MALLOC_FAILURE);
			goto f_err;
			}
		}
#endif /* !OPENSSL_NO_PSK */

	if (0) {}
	else if (alg_k & SSL_kRSA)
		{
		CBS rsa_modulus, rsa_exponent;

		/* TODO(davidben): This was originally for export
		 * reasons. Do we still need to support it? */

		if (!CBS_get_u16_length_prefixed(&server_key_exchange, &rsa_modulus) ||
			CBS_len(&rsa_modulus) == 0 ||
			!CBS_get_u16_length_prefixed(&server_key_exchange, &rsa_exponent) ||
			CBS_len(&rsa_exponent) == 0)
			{
			al = SSL_AD_DECODE_ERROR;
			OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, SSL_R_DECODE_ERROR);
			goto f_err;
			}

		if ((rsa=RSA_new()) == NULL)
			{
			OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, ERR_R_MALLOC_FAILURE);
			goto err;
			}

		if (!(rsa->n = BN_bin2bn(CBS_data(&rsa_modulus),
					CBS_len(&rsa_modulus), rsa->n)))
			{
			OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, ERR_R_BN_LIB);
			goto err;
			}

		if (!(rsa->e = BN_bin2bn(CBS_data(&rsa_exponent),
					CBS_len(&rsa_exponent), rsa->e)))
			{
			OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, ERR_R_BN_LIB);
			goto err;
			}

		/* this should be because we are using an export cipher */
		if (alg_a & SSL_aRSA)
			pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509);
		else
			{
			OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, ERR_R_INTERNAL_ERROR);
			goto err;
			}
		s->session->sess_cert->peer_rsa_tmp=rsa;
		rsa=NULL;
		}
#ifndef OPENSSL_NO_DH
	else if (alg_k & SSL_kEDH)
		{
		CBS dh_p, dh_g, dh_Ys;

		if (!CBS_get_u16_length_prefixed(&server_key_exchange, &dh_p) ||
			CBS_len(&dh_p) == 0 ||
			!CBS_get_u16_length_prefixed(&server_key_exchange, &dh_g) ||
			CBS_len(&dh_g) == 0 ||
			!CBS_get_u16_length_prefixed(&server_key_exchange, &dh_Ys) ||
			CBS_len(&dh_Ys) == 0)
			{
			al = SSL_AD_DECODE_ERROR;
			OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, SSL_R_DECODE_ERROR);
			goto f_err;
			}

		if ((dh=DH_new()) == NULL)
			{
			OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, ERR_R_DH_LIB);
			goto err;
			}

		if (!(dh->p = BN_bin2bn(CBS_data(&dh_p), CBS_len(&dh_p), NULL)))
			{
			OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, ERR_R_BN_LIB);
			goto err;
			}
		if (!(dh->g=BN_bin2bn(CBS_data(&dh_g), CBS_len(&dh_g), NULL)))
			{
			OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, ERR_R_BN_LIB);
			goto err;
			}
		if (!(dh->pub_key = BN_bin2bn(CBS_data(&dh_Ys), CBS_len(&dh_Ys), NULL)))
			{
			OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, ERR_R_BN_LIB);
			goto err;
			}

		if (alg_a & SSL_aRSA)
			pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509);
#ifndef OPENSSL_NO_DSA
		else if (alg_a & SSL_aDSS)
			pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_DSA_SIGN].x509);
#endif
		/* else anonymous DH, so no certificate or pkey. */

		s->session->sess_cert->peer_dh_tmp=dh;
		dh=NULL;
		}
	else if ((alg_k & SSL_kDHr) || (alg_k & SSL_kDHd))
		{
		al=SSL_AD_ILLEGAL_PARAMETER;
		OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, SSL_R_TRIED_TO_USE_UNSUPPORTED_CIPHER);
		goto f_err;
		}
#endif /* !OPENSSL_NO_DH */

#ifndef OPENSSL_NO_ECDH
	else if (alg_k & SSL_kEECDH)
		{
		uint16_t curve_id;
		int curve_nid = 0;
		EC_GROUP *ngroup;
		const EC_GROUP *group;
		CBS point;

		/* Extract elliptic curve parameters and the server's
		 * ephemeral ECDH public key.  Check curve is one of
		 * our preferences, if not server has sent an invalid
		 * curve.
		 */
		if (!tls1_check_curve(s, &server_key_exchange, &curve_id))
			{
			al = SSL_AD_DECODE_ERROR;
			OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, SSL_R_WRONG_CURVE);
			goto f_err;
			}

		if ((curve_nid = tls1_ec_curve_id2nid(curve_id)) == 0)
			{
			al=SSL_AD_INTERNAL_ERROR;
			OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS);
			goto f_err;
			}

		if ((ecdh=EC_KEY_new()) == NULL)
			{
			OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, ERR_R_MALLOC_FAILURE);
			goto err;
			}
		ngroup = EC_GROUP_new_by_curve_name(curve_nid);
		if (ngroup == NULL)
			{
			OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, ERR_R_EC_LIB);
			goto err;
			}
		if (EC_KEY_set_group(ecdh, ngroup) == 0)
			{
			OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, ERR_R_EC_LIB);
			goto err;
			}
		EC_GROUP_free(ngroup);

		group = EC_KEY_get0_group(ecdh);

		if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) &&
		    (EC_GROUP_get_degree(group) > 163))
			{
			al=SSL_AD_EXPORT_RESTRICTION;
			OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER);
			goto f_err;
			}

		/* Next, get the encoded ECPoint */
		if (!CBS_get_u8_length_prefixed(&server_key_exchange, &point))
			{
			al = SSL_AD_DECODE_ERROR;
			OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, SSL_R_DECODE_ERROR);
			goto f_err;
			}

		if (((srvr_ecpoint = EC_POINT_new(group)) == NULL) ||
		    ((bn_ctx = BN_CTX_new()) == NULL))
			{
			OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, ERR_R_MALLOC_FAILURE);
			goto err;
			}

		if (!EC_POINT_oct2point(group, srvr_ecpoint,
				CBS_data(&point), CBS_len(&point), bn_ctx))
			{
			al = SSL_AD_DECODE_ERROR;
			OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, SSL_R_BAD_ECPOINT);
			goto f_err;
			}

		/* The ECC/TLS specification does not mention
		 * the use of DSA to sign ECParameters in the server
		 * key exchange message. We do support RSA and ECDSA.
		 */
		if (0) ;
		else if (alg_a & SSL_aRSA)
			pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509);
#ifndef OPENSSL_NO_ECDSA
		else if (alg_a & SSL_aECDSA)
			pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_ECC].x509);
#endif
		/* else anonymous ECDH, so no certificate or pkey. */
		EC_KEY_set_public_key(ecdh, srvr_ecpoint);
		s->session->sess_cert->peer_ecdh_tmp=ecdh;
		ecdh=NULL;
		BN_CTX_free(bn_ctx);
		bn_ctx = NULL;
		EC_POINT_free(srvr_ecpoint);
		srvr_ecpoint = NULL;
		}
#endif /* !OPENSSL_NO_ECDH */

	else if (!(alg_k & SSL_kPSK))
		{
		al=SSL_AD_UNEXPECTED_MESSAGE;
		OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, SSL_R_UNEXPECTED_MESSAGE);
		goto f_err;
		}

	/* At this point, |server_key_exchange| contains the
	 * signature, if any, while |server_key_exchange_orig|
	 * contains the entire message. From that, derive a CBS
	 * containing just the parameter. */
	CBS_init(&parameter, CBS_data(&server_key_exchange_orig),
		CBS_len(&server_key_exchange_orig) -
		CBS_len(&server_key_exchange));

	/* if it was signed, check the signature */
	if (pkey != NULL)
		{
		CBS signature;

		if (SSL_USE_SIGALGS(s))
			{
			if (!tls12_check_peer_sigalg(&md, &al, s, &server_key_exchange, pkey))
				goto f_err;
			}
		else
			md = EVP_sha1();

		/* The last field in |server_key_exchange| is the
		 * signature. */
		if (!CBS_get_u16_length_prefixed(&server_key_exchange, &signature) ||
			CBS_len(&server_key_exchange) != 0)
			{
			al = SSL_AD_DECODE_ERROR;
			OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, SSL_R_DECODE_ERROR);
			goto f_err;
			}

		if (pkey->type == EVP_PKEY_RSA && !SSL_USE_SIGALGS(s))
			{
			int num;
			unsigned char *q, md_buf[EVP_MAX_MD_SIZE*2];
			size_t md_len = 0;

			q=md_buf;
			for (num=2; num > 0; num--)
				{
				unsigned int digest_len;
				EVP_DigestInit_ex(&md_ctx,(num == 2)
					?s->ctx->md5:s->ctx->sha1, NULL);
				EVP_DigestUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE);
				EVP_DigestUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE);
				EVP_DigestUpdate(&md_ctx, CBS_data(&parameter), CBS_len(&parameter));
				EVP_DigestFinal_ex(&md_ctx, q, &digest_len);
				q += digest_len;
				md_len += digest_len;
				}
			if (!RSA_verify(NID_md5_sha1, md_buf, md_len,
					CBS_data(&signature), CBS_len(&signature),
					pkey->pkey.rsa))
				{
				al = SSL_AD_DECRYPT_ERROR;
				OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, SSL_R_BAD_SIGNATURE);
				goto f_err;
				}
			}
		else
			{
			EVP_VerifyInit_ex(&md_ctx, md, NULL);
			EVP_VerifyUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE);
			EVP_VerifyUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE);
			EVP_VerifyUpdate(&md_ctx, CBS_data(&parameter), CBS_len(&parameter));
			if (EVP_VerifyFinal(&md_ctx, CBS_data(&signature), CBS_len(&signature), pkey) <= 0)
				{
				/* bad signature */
				al=SSL_AD_DECRYPT_ERROR;
				OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, SSL_R_BAD_SIGNATURE);
				goto f_err;
				}
			}
		}
	else
		{
		if (ssl_cipher_has_server_public_key(s->s3->tmp.new_cipher))
			{
			/* Might be wrong key type, check it */
			if (ssl3_check_cert_and_algorithm(s))
				/* Otherwise this shouldn't happen */
				OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, ERR_R_INTERNAL_ERROR);
			goto err;
			}
		/* still data left over */
		if (CBS_len(&server_key_exchange) > 0)
			{
			al=SSL_AD_DECODE_ERROR;
			OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, SSL_R_EXTRA_DATA_IN_MESSAGE);
			goto f_err;
			}
		}
	EVP_PKEY_free(pkey);
	EVP_MD_CTX_cleanup(&md_ctx);
	return(1);
f_err:
	ssl3_send_alert(s,SSL3_AL_FATAL,al);
err:
	EVP_PKEY_free(pkey);
	if (rsa != NULL)
		RSA_free(rsa);
#ifndef OPENSSL_NO_DH
	if (dh != NULL)
		DH_free(dh);
#endif
#ifndef OPENSSL_NO_ECDH
	BN_CTX_free(bn_ctx);
	EC_POINT_free(srvr_ecpoint);
	if (ecdh != NULL)
		EC_KEY_free(ecdh);
#endif
	EVP_MD_CTX_cleanup(&md_ctx);
	return(-1);
	}

static int ca_dn_cmp(const X509_NAME **a, const X509_NAME **b)
	{
	return(X509_NAME_cmp(*a,*b));
	}

int ssl3_get_certificate_request(SSL *s)
	{
	int ok,ret=0;
	unsigned long n;
	unsigned int i;
	X509_NAME *xn=NULL;
	STACK_OF(X509_NAME) *ca_sk=NULL;
	CBS cbs;
	CBS certificate_types;
	CBS certificate_authorities;
	const uint8_t *data;

	n=s->method->ssl_get_message(s,
		SSL3_ST_CR_CERT_REQ_A,
		SSL3_ST_CR_CERT_REQ_B,
		-1,
		s->max_cert_list,
		&ok);

	if (!ok) return((int)n);

	s->s3->tmp.cert_req=0;

	if (s->s3->tmp.message_type == SSL3_MT_SERVER_DONE)
		{
		s->s3->tmp.reuse_message=1;
		/* If we get here we don't need any cached handshake records
		 * as we wont be doing client auth.
		 */
		if (s->s3->handshake_buffer)
			{
			if (!ssl3_digest_cached_records(s))
				goto err;
			}
		return(1);
		}

	if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE_REQUEST)
		{
		ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_UNEXPECTED_MESSAGE);
		OPENSSL_PUT_ERROR(SSL, ssl3_get_certificate_request, SSL_R_WRONG_MESSAGE_TYPE);
		goto err;
		}

	/* TLS does not like anon-DH with client cert */
	if (s->version > SSL3_VERSION)
		{
		if (s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL)
			{
			ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_UNEXPECTED_MESSAGE);
			OPENSSL_PUT_ERROR(SSL, ssl3_get_certificate_request, SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER);
			goto err;
			}
		}

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

	ca_sk = sk_X509_NAME_new(ca_dn_cmp);
	if (ca_sk == NULL)
		{
		OPENSSL_PUT_ERROR(SSL, ssl3_get_certificate_request, ERR_R_MALLOC_FAILURE);
		goto err;
		}

	/* get the certificate types */
	if (!CBS_get_u8_length_prefixed(&cbs, &certificate_types))
		{
		ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
		OPENSSL_PUT_ERROR(SSL, ssl3_get_certificate_request, SSL_R_DECODE_ERROR);
		goto err;
		}
	if (!CBS_stow(&certificate_types,
			&s->s3->tmp.certificate_types,
			&s->s3->tmp.num_certificate_types))
		{
		ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
		goto err;
		}
	if (SSL_USE_SIGALGS(s))
		{
		CBS supported_signature_algorithms;
		if (!CBS_get_u16_length_prefixed(&cbs, &supported_signature_algorithms))
			{
			ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR);
			OPENSSL_PUT_ERROR(SSL, ssl3_get_certificate_request, SSL_R_DECODE_ERROR);
			goto err;
			}
		/* Clear certificate digests and validity flags */
		for (i = 0; i < SSL_PKEY_NUM; i++)
			{
			s->cert->pkeys[i].digest = NULL;
			s->cert->pkeys[i].valid_flags = 0;
			}
		if (!tls1_process_sigalgs(s,
				CBS_data(&supported_signature_algorithms),
				CBS_len(&supported_signature_algorithms)))
			{
			ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR);
			OPENSSL_PUT_ERROR(SSL, ssl3_get_certificate_request, SSL_R_SIGNATURE_ALGORITHMS_ERROR);
			goto err;
			}
		}

	/* get the CA RDNs */
	if (!CBS_get_u16_length_prefixed(&cbs, &certificate_authorities))
		{
		ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR);
		OPENSSL_PUT_ERROR(SSL, ssl3_get_certificate_request, SSL_R_LENGTH_MISMATCH);
		goto err;
		}

	while (CBS_len(&certificate_authorities) > 0)
		{
		CBS distinguished_name;
		if (!CBS_get_u16_length_prefixed(&certificate_authorities, &distinguished_name))
			{
			ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR);
			OPENSSL_PUT_ERROR(SSL, ssl3_get_certificate_request, SSL_R_CA_DN_TOO_LONG);
			goto err;
			}

		data = CBS_data(&distinguished_name);
		if ((xn=d2i_X509_NAME(NULL, &data, CBS_len(&distinguished_name))) == NULL)
			{
			ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR);
			OPENSSL_PUT_ERROR(SSL, ssl3_get_certificate_request, ERR_R_ASN1_LIB);
			goto err;
			}

		if (!CBS_skip(&distinguished_name, data - CBS_data(&distinguished_name)))
			{
			ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR);
			OPENSSL_PUT_ERROR(SSL, ssl3_get_server_certificate, ERR_R_INTERNAL_ERROR);
			goto err;
			}
		if (CBS_len(&distinguished_name) != 0)
			{
			ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR);
			OPENSSL_PUT_ERROR(SSL, ssl3_get_certificate_request, SSL_R_CA_DN_LENGTH_MISMATCH);
			goto err;
			}
		if (!sk_X509_NAME_push(ca_sk,xn))
			{
			OPENSSL_PUT_ERROR(SSL, ssl3_get_certificate_request, ERR_R_MALLOC_FAILURE);
			goto err;
			}
		}

	/* we should setup a certificate to return.... */
	s->s3->tmp.cert_req=1;
	if (s->s3->tmp.ca_names != NULL)
		sk_X509_NAME_pop_free(s->s3->tmp.ca_names,X509_NAME_free);
	s->s3->tmp.ca_names=ca_sk;
	ca_sk=NULL;

	ret=1;
err:
	if (ca_sk != NULL) sk_X509_NAME_pop_free(ca_sk,X509_NAME_free);
	return(ret);
	}

int ssl3_get_new_session_ticket(SSL *s)
	{
	int ok,al,ret=0;
	long n;
	CBS new_session_ticket, ticket;

	n=s->method->ssl_get_message(s,
		SSL3_ST_CR_SESSION_TICKET_A,
		SSL3_ST_CR_SESSION_TICKET_B,
		SSL3_MT_NEWSESSION_TICKET,
		16384,
		&ok);

	if (!ok)
		return((int)n);

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

	if (!CBS_get_u32(&new_session_ticket, &s->session->tlsext_tick_lifetime_hint) ||
		!CBS_get_u16_length_prefixed(&new_session_ticket, &ticket) ||
		CBS_len(&new_session_ticket) != 0)
		{
		al = SSL_AD_DECODE_ERROR;
		OPENSSL_PUT_ERROR(SSL, ssl3_get_new_session_ticket, SSL_R_DECODE_ERROR);
		goto f_err;
		}

	if (!CBS_stow(&ticket, &s->session->tlsext_tick, &s->session->tlsext_ticklen))
		{
		OPENSSL_PUT_ERROR(SSL, ssl3_get_new_session_ticket, ERR_R_MALLOC_FAILURE);
		goto err;
		}

	/* There are two ways to detect a resumed ticket sesion.
	 * One is to set an appropriate session ID and then the server
	 * must return a match in ServerHello. This allows the normal
	 * client session ID matching to work and we know much 
	 * earlier that the ticket has been accepted.
	 * 
	 * The other way is to set zero length session ID when the
	 * ticket is presented and rely on the handshake to determine
	 * session resumption.
	 *
	 * We choose the former approach because this fits in with
	 * assumptions elsewhere in OpenSSL. The session ID is set
	 * to the SHA256 (or SHA1 is SHA256 is disabled) hash of the
	 * ticket.
	 */ 
	EVP_Digest(CBS_data(&ticket), CBS_len(&ticket),
			s->session->session_id, &s->session->session_id_length,
#ifndef OPENSSL_NO_SHA256
							EVP_sha256(), NULL);
#else
							EVP_sha1(), NULL);
#endif
	ret=1;
	return(ret);
f_err:
	ssl3_send_alert(s,SSL3_AL_FATAL,al);
err:
	return(-1);
	}

int ssl3_get_cert_status(SSL *s)
	{
	int ok, al;
	long n;
	CBS certificate_status, ocsp_response;
	uint8_t status_type;
	size_t resplen;

	n=s->method->ssl_get_message(s,
		SSL3_ST_CR_CERT_STATUS_A,
		SSL3_ST_CR_CERT_STATUS_B,
		SSL3_MT_CERTIFICATE_STATUS,
		16384,
		&ok);

	if (!ok) return((int)n);

	CBS_init(&certificate_status, s->init_msg, n);
	if (!CBS_get_u8(&certificate_status, &status_type) ||
		status_type != TLSEXT_STATUSTYPE_ocsp ||
		!CBS_get_u24_length_prefixed(&certificate_status, &ocsp_response) ||
		CBS_len(&ocsp_response) == 0 ||
		CBS_len(&certificate_status) != 0)
		{
		al = SSL_AD_DECODE_ERROR;
		OPENSSL_PUT_ERROR(SSL, ssl3_get_cert_status, SSL_R_DECODE_ERROR);
		goto f_err;
		}

	/* TODO(davidben): Make tlsext_ocsp_resplen a
	 * size_t. Currently it uses -1 to signal no response. The
	 * spec does not allow ocsp_response to be zero-length, so
	 * using 0 should be fine. */
	if (!CBS_stow(&ocsp_response, &s->tlsext_ocsp_resp, &resplen))
		{
		al = SSL_AD_INTERNAL_ERROR;
		OPENSSL_PUT_ERROR(SSL, ssl3_get_cert_status, ERR_R_MALLOC_FAILURE);
		goto f_err;
		}
	s->tlsext_ocsp_resplen = resplen;
	if (s->ctx->tlsext_status_cb)
		{
		int ret;
		ret = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg);
		if (ret == 0)
			{
			al = SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE;
			OPENSSL_PUT_ERROR(SSL, ssl3_get_cert_status, SSL_R_INVALID_STATUS_RESPONSE);
			goto f_err;
			}
		if (ret < 0)
			{
			al = SSL_AD_INTERNAL_ERROR;
			OPENSSL_PUT_ERROR(SSL, ssl3_get_cert_status, ERR_R_MALLOC_FAILURE);
			goto f_err;
			}
		}
	return 1;
f_err:
	ssl3_send_alert(s,SSL3_AL_FATAL,al);
	return(-1);
	}

int ssl3_get_server_done(SSL *s)
	{
	int ok,ret=0;
	long n;

	n=s->method->ssl_get_message(s,
		SSL3_ST_CR_SRVR_DONE_A,
		SSL3_ST_CR_SRVR_DONE_B,
		SSL3_MT_SERVER_DONE,
		30, /* should be very small, like 0 :-) */
		&ok);

	if (!ok) return((int)n);
	if (n > 0)
		{
		/* should contain no data */
		ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR);
		OPENSSL_PUT_ERROR(SSL, ssl3_get_server_done, SSL_R_LENGTH_MISMATCH);
		return -1;
		}
	ret=1;
	return(ret);
	}


int ssl3_send_client_key_exchange(SSL *s)
	{
	unsigned char *p;
	int n = 0;
	unsigned long alg_k;
	unsigned long alg_a;
	unsigned char *q;
	EVP_PKEY *pkey=NULL;
#ifndef OPENSSL_NO_ECDH
	EC_KEY *clnt_ecdh = NULL;
	const EC_POINT *srvr_ecpoint = NULL;
	EVP_PKEY *srvr_pub_pkey = NULL;
	unsigned char *encodedPoint = NULL;
	int encoded_pt_len = 0;
	BN_CTX * bn_ctx = NULL;
#ifndef OPENSSL_NO_PSK
	unsigned int psk_len = 0;
	unsigned char psk[PSK_MAX_PSK_LEN];
#endif /* OPENSSL_NO_PSK */
#endif /* OPENSSL_NO_ECDH */

	if (s->state == SSL3_ST_CW_KEY_EXCH_A)
		{
		p = ssl_handshake_start(s);

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

#ifndef OPENSSL_NO_PSK
		if (alg_a & SSL_aPSK)
			{
			char identity[PSK_MAX_IDENTITY_LEN + 1];
			size_t identity_len;
			unsigned char *t = NULL;
			unsigned char pre_ms[PSK_MAX_PSK_LEN*2+4];
			unsigned int pre_ms_len = 0;
			int psk_err = 1;

			n = 0;
			if (s->psk_client_callback == NULL)
				{
				OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, SSL_R_PSK_NO_CLIENT_CB);
				goto err;
				}

			memset(identity, 0, sizeof(identity));
			psk_len = s->psk_client_callback(s, s->session->psk_identity_hint,
				identity, sizeof(identity), psk, sizeof(psk));
			if (psk_len > PSK_MAX_PSK_LEN)
				{
				OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_INTERNAL_ERROR);
				goto psk_err;
				}
			else if (psk_len == 0)
				{
				OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, SSL_R_PSK_IDENTITY_NOT_FOUND);
				goto psk_err;
				}
			identity_len = OPENSSL_strnlen(identity, sizeof(identity));
			if (identity_len > PSK_MAX_IDENTITY_LEN)
				{
				OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_INTERNAL_ERROR);
				goto psk_err;
				}

			if (!(alg_k & SSL_kEECDH))
				{
				/* Create the shared secret now if we're not using ECDHE-PSK.
				 * TODO(davidben): Refactor this logic similarly
				 * to ssl3_get_client_key_exchange. */
				pre_ms_len = 2+psk_len+2+psk_len;
				t = pre_ms;
				s2n(psk_len, t);
				memset(t, 0, psk_len);
				t+=psk_len;
				s2n(psk_len, t);
				memcpy(t, psk, psk_len);

				s->session->master_key_length =
					s->method->ssl3_enc->generate_master_secret(s,
						s->session->master_key,
						pre_ms, pre_ms_len);
				s2n(identity_len, p);
				memcpy(p, identity, identity_len);
				n = 2 + identity_len;
				}

			if (s->session->psk_identity != NULL)
				OPENSSL_free(s->session->psk_identity);
			s->session->psk_identity = BUF_strdup(identity);
			if (s->session->psk_identity == NULL)
				{
				OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_MALLOC_FAILURE);
				goto psk_err;
				}
			psk_err = 0;
		psk_err:
			OPENSSL_cleanse(identity, PSK_MAX_IDENTITY_LEN);
			OPENSSL_cleanse(pre_ms, sizeof(pre_ms));
			if (psk_err != 0)
				{
				ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
				goto err;
				}
			}
#endif

		/* Fool emacs indentation */
		if (0) {}
		else if (alg_k & SSL_kRSA)
			{
			RSA *rsa;
			unsigned char tmp_buf[SSL_MAX_MASTER_KEY_LENGTH];

			if (s->session->sess_cert->peer_rsa_tmp != NULL)
				rsa=s->session->sess_cert->peer_rsa_tmp;
			else
				{
				pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509);
				if ((pkey == NULL) ||
					(pkey->type != EVP_PKEY_RSA) ||
					(pkey->pkey.rsa == NULL))
					{
					OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_INTERNAL_ERROR);
					goto err;
					}
				rsa=pkey->pkey.rsa;
				EVP_PKEY_free(pkey);
				}
				
			tmp_buf[0]=s->client_version>>8;
			tmp_buf[1]=s->client_version&0xff;
			if (RAND_bytes(&(tmp_buf[2]),sizeof tmp_buf-2) <= 0)
					goto err;

			s->session->master_key_length=sizeof tmp_buf;

			q=p;
			/* Fix buf for TLS and beyond */
			if (s->version > SSL3_VERSION)
				p+=2;
			n=RSA_public_encrypt(sizeof tmp_buf,
				tmp_buf,p,rsa,RSA_PKCS1_PADDING);
#ifdef PKCS1_CHECK
			if (s->options & SSL_OP_PKCS1_CHECK_1) p[1]++;
			if (s->options & SSL_OP_PKCS1_CHECK_2) tmp_buf[0]=0x70;
#endif
			if (n <= 0)
				{
				OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, SSL_R_BAD_RSA_ENCRYPT);
				goto err;
				}

			/* Fix buf for TLS and beyond */
			if (s->version > SSL3_VERSION)
				{
				s2n(n,q);
				n+=2;
				}

			s->session->master_key_length=
				s->method->ssl3_enc->generate_master_secret(s,
					s->session->master_key,
					tmp_buf,sizeof tmp_buf);
			OPENSSL_cleanse(tmp_buf,sizeof tmp_buf);
			}
#ifndef OPENSSL_NO_DH
		else if (alg_k & (SSL_kEDH|SSL_kDHr|SSL_kDHd))
			{
			DH *dh_srvr,*dh_clnt;
			SESS_CERT *scert = s->session->sess_cert;

			if (scert == NULL) 
				{
				ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_UNEXPECTED_MESSAGE);
				OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, SSL_R_UNEXPECTED_MESSAGE);
				goto err;
				}

			if (scert->peer_dh_tmp != NULL)
				dh_srvr=scert->peer_dh_tmp;
			else
				{
				/* we get them from the cert */
				int idx = scert->peer_cert_type;
				EVP_PKEY *spkey = NULL;
				dh_srvr = NULL;
				if (idx >= 0)
					spkey = X509_get_pubkey(
						scert->peer_pkeys[idx].x509);
				if (spkey)
					{
					dh_srvr = EVP_PKEY_get1_DH(spkey);
					EVP_PKEY_free(spkey);
					}
				if (dh_srvr == NULL)
					{
					OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_INTERNAL_ERROR);
					goto err;
					}
				}
			if (s->s3->flags & TLS1_FLAGS_SKIP_CERT_VERIFY)
				{
				/* Use client certificate key */
				EVP_PKEY *clkey = s->cert->key->privatekey;
				dh_clnt = NULL;
				if (clkey)
					dh_clnt = EVP_PKEY_get1_DH(clkey);
				if (dh_clnt == NULL)
					{
					OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_INTERNAL_ERROR);
					goto err;
					}
				}
			else
				{
				/* generate a new random key */
				if ((dh_clnt=DHparams_dup(dh_srvr)) == NULL)
					{
					OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_DH_LIB);
					goto err;
					}
				if (!DH_generate_key(dh_clnt))
					{
					OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_DH_LIB);
					DH_free(dh_clnt);
					goto err;
					}
				}

			/* use the 'p' output buffer for the DH key, but
			 * make sure to clear it out afterwards */

			n=DH_compute_key(p,dh_srvr->pub_key,dh_clnt);
			if (scert->peer_dh_tmp == NULL)
				DH_free(dh_srvr);

			if (n <= 0)
				{
				OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_DH_LIB);
				DH_free(dh_clnt);
				goto err;
				}

			/* generate master key from the result */
			s->session->master_key_length=
				s->method->ssl3_enc->generate_master_secret(s,
					s->session->master_key,p,n);
			/* clean up */
			memset(p,0,n);

			if (s->s3->flags & TLS1_FLAGS_SKIP_CERT_VERIFY)
				n = 0;
			else
				{
				/* send off the data */
				n=BN_num_bytes(dh_clnt->pub_key);
				s2n(n,p);
				BN_bn2bin(dh_clnt->pub_key,p);
				n+=2;
				}

			DH_free(dh_clnt);

			/* perhaps clean things up a bit EAY EAY EAY EAY*/
			}
#endif

#ifndef OPENSSL_NO_ECDH
		else if (alg_k & (SSL_kEECDH|SSL_kECDHr|SSL_kECDHe))
			{
			const EC_GROUP *srvr_group = NULL;
			EC_KEY *tkey;
			int ecdh_clnt_cert = 0;
			int field_size = 0;
#ifndef OPENSSL_NO_PSK
			unsigned char *pre_ms;
			unsigned char *t;
			unsigned int pre_ms_len;
			unsigned int i;
#endif

			if (s->session->sess_cert == NULL) 
				{
				ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_UNEXPECTED_MESSAGE);
				OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, SSL_R_UNEXPECTED_MESSAGE);
				goto err;
				}

			/* Did we send out the client's
			 * ECDH share for use in premaster
			 * computation as part of client certificate?
			 * If so, set ecdh_clnt_cert to 1.
			 */
			if ((alg_k & (SSL_kECDHr|SSL_kECDHe)) && (s->cert != NULL)) 
				{
				/* XXX: For now, we do not support client
				 * authentication using ECDH certificates.
				 * To add such support, one needs to add
				 * code that checks for appropriate 
				 * conditions and sets ecdh_clnt_cert to 1.
				 * For example, the cert have an ECC
				 * key on the same curve as the server's
				 * and the key should be authorized for
				 * key agreement.
				 *
				 * One also needs to add code in ssl3_connect
				 * to skip sending the certificate verify
				 * message.
				 *
				 * if ((s->cert->key->privatekey != NULL) &&
				 *     (s->cert->key->privatekey->type ==
				 *      EVP_PKEY_EC) && ...)
				 * ecdh_clnt_cert = 1;
				 */
				}

			if (s->session->sess_cert->peer_ecdh_tmp != NULL)
				{
				tkey = s->session->sess_cert->peer_ecdh_tmp;
				}
			else
				{
				/* Get the Server Public Key from Cert */
				srvr_pub_pkey = X509_get_pubkey(s->session-> \
				    sess_cert->peer_pkeys[SSL_PKEY_ECC].x509);
				if ((srvr_pub_pkey == NULL) ||
				    (srvr_pub_pkey->type != EVP_PKEY_EC) ||
				    (srvr_pub_pkey->pkey.ec == NULL))
					{
					OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_INTERNAL_ERROR);
					goto err;
					}

				tkey = srvr_pub_pkey->pkey.ec;
				}

			srvr_group   = EC_KEY_get0_group(tkey);
			srvr_ecpoint = EC_KEY_get0_public_key(tkey);

			if ((srvr_group == NULL) || (srvr_ecpoint == NULL))
				{
				OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_INTERNAL_ERROR);
				goto err;
				}

			if ((clnt_ecdh=EC_KEY_new()) == NULL) 
				{
				OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_MALLOC_FAILURE);
				goto err;
				}

			if (!EC_KEY_set_group(clnt_ecdh, srvr_group))
				{
				OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_EC_LIB);
				goto err;
				}
			if (ecdh_clnt_cert) 
				{ 
				/* Reuse key info from our certificate
				 * We only need our private key to perform
				 * the ECDH computation.
				 */
				const BIGNUM *priv_key;
				tkey = s->cert->key->privatekey->pkey.ec;
				priv_key = EC_KEY_get0_private_key(tkey);
				if (priv_key == NULL)
					{
					OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_MALLOC_FAILURE);
					goto err;
					}
				if (!EC_KEY_set_private_key(clnt_ecdh, priv_key))
					{
					OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_EC_LIB);
					goto err;
					}
				}
			else 
				{
				/* Generate a new ECDH key pair */
				if (!(EC_KEY_generate_key(clnt_ecdh)))
					{
					OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_ECDH_LIB);
					goto err;
					}
				}

			/* use the 'p' output buffer for the ECDH key, but
			 * make sure to clear it out afterwards
			 */

			field_size = EC_GROUP_get_degree(srvr_group);
			if (field_size <= 0)
				{
				OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_ECDH_LIB);
				goto err;
				}
			n=ECDH_compute_key(p, (field_size+7)/8, srvr_ecpoint, clnt_ecdh, NULL);
			if (n <= 0)
				{
				OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_ECDH_LIB);
				goto err;
				}

#ifndef OPENSSL_NO_PSK
			/* ECDHE PSK ciphersuites from RFC 5489 */
			if ((alg_a & SSL_aPSK) && psk_len != 0)
				{
				pre_ms_len = 2+psk_len+2+n;
				pre_ms = OPENSSL_malloc(pre_ms_len);
				if (pre_ms == NULL)
					{
					OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_MALLOC_FAILURE);
					goto err;
					}
				memset(pre_ms, 0, pre_ms_len);
				t = pre_ms;
				s2n(psk_len, t);
				memcpy(t, psk, psk_len);
				t += psk_len;
				s2n(n, t);
				memcpy(t, p, n);
				s->session->master_key_length = s->method->ssl3_enc \
					-> generate_master_secret(s,
						s->session->master_key, pre_ms, pre_ms_len);
				OPENSSL_cleanse(pre_ms, pre_ms_len);
				OPENSSL_free(pre_ms);
				}
#endif /* OPENSSL_NO_PSK */
			if (!(alg_a & SSL_aPSK))
				{
				/* generate master key from the result */
				s->session->master_key_length = s->method->ssl3_enc \
					-> generate_master_secret(s,
						s->session->master_key, p, n);
				}
			memset(p, 0, n); /* clean up */

			if (ecdh_clnt_cert)
				{
				/* Send empty client key exch message */
				n = 0;
				}
			else 
				{
				/* First check the size of encoding and
				 * allocate memory accordingly.
				 */
				encoded_pt_len = 
				    EC_POINT_point2oct(srvr_group, 
					EC_KEY_get0_public_key(clnt_ecdh), 
					POINT_CONVERSION_UNCOMPRESSED, 
					NULL, 0, NULL);

				encodedPoint = (unsigned char *) 
				    OPENSSL_malloc(encoded_pt_len * 
					sizeof(unsigned char)); 
				bn_ctx = BN_CTX_new();
				if ((encodedPoint == NULL) || 
				    (bn_ctx == NULL)) 
					{
					OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_MALLOC_FAILURE);
					goto err;
					}

				/* Encode the public key */
				encoded_pt_len = EC_POINT_point2oct(srvr_group,
				    EC_KEY_get0_public_key(clnt_ecdh),
				    POINT_CONVERSION_UNCOMPRESSED,
				    encodedPoint, encoded_pt_len, bn_ctx);

				n = 0;
#ifndef OPENSSL_NO_PSK
				if ((alg_a & SSL_aPSK) && psk_len != 0)
					{
					i = strlen(s->session->psk_identity);
					s2n(i, p);
					memcpy(p, s->session->psk_identity, i);
					p += i;
					n = i + 2;
					}
#endif

				*p = encoded_pt_len; /* length of encoded point */
				/* Encoded point will be copied here */
				p += 1;
				n += 1;
				/* copy the point */
				memcpy((unsigned char *)p, encodedPoint, encoded_pt_len);
				/* increment n to account for length field */
				n += encoded_pt_len;
				}

			/* Free allocated memory */
			BN_CTX_free(bn_ctx);
			if (encodedPoint != NULL) OPENSSL_free(encodedPoint);
			if (clnt_ecdh != NULL)
				 EC_KEY_free(clnt_ecdh);
			EVP_PKEY_free(srvr_pub_pkey);
			}
#endif /* !OPENSSL_NO_ECDH */
		else if (alg_k & SSL_kGOST)
			{
			OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, SSL_R_GOST_NOT_SUPPORTED);
			goto err;
			}
		else if (!(alg_k & SSL_kPSK) || ((alg_k & SSL_kPSK) && !(alg_a & SSL_aPSK)))
			{
			ssl3_send_alert(s, SSL3_AL_FATAL,
			    SSL_AD_HANDSHAKE_FAILURE);
			OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_INTERNAL_ERROR);
			goto err;
			}

		ssl_set_handshake_header(s, SSL3_MT_CLIENT_KEY_EXCHANGE, n);
		s->state=SSL3_ST_CW_KEY_EXCH_B;
		}

	/* SSL3_ST_CW_KEY_EXCH_B */
	return ssl_do_write(s);
err:
#ifndef OPENSSL_NO_ECDH
	BN_CTX_free(bn_ctx);
	if (encodedPoint != NULL) OPENSSL_free(encodedPoint);
	if (clnt_ecdh != NULL) 
		EC_KEY_free(clnt_ecdh);
	EVP_PKEY_free(srvr_pub_pkey);
#endif
	return(-1);
	}

int ssl3_send_client_verify(SSL *s)
	{
	unsigned char *buf, *p;
	const EVP_MD *md;
	uint8_t digest[EVP_MAX_MD_SIZE];
	unsigned digest_length;
	EVP_PKEY *pkey;
	EVP_PKEY_CTX *pctx = NULL;
	EVP_MD_CTX mctx;
	size_t signature_length = 0;
	unsigned long n = 0;

	EVP_MD_CTX_init(&mctx);
	buf=(unsigned char *)s->init_buf->data;

	if (s->state == SSL3_ST_CW_CERT_VRFY_A)
		{
		p= ssl_handshake_start(s);
		pkey = s->cert->key->privatekey;
		/* For TLS v1.2 send signature algorithm and signature using
		 * agreed digest and cached handshake records. Otherwise, use
		 * SHA1 or MD5 + SHA1 depending on key type.
		 */
		if (SSL_USE_SIGALGS(s))
			{
			const uint8_t *hdata;
			size_t hdatalen;
			md = s->cert->key->digest;
			if (!BIO_mem_contents(s->s3->handshake_buffer, &hdata, &hdatalen) ||
			    !tls12_get_sigandhash(p, pkey, md))
				{
				OPENSSL_PUT_ERROR(SSL, ssl3_send_client_verify, ERR_R_INTERNAL_ERROR);
				goto err;
				}
			p += 2;
			n += 2;
			if (!EVP_DigestInit_ex(&mctx, md, NULL)
				|| !EVP_DigestUpdate(&mctx, hdata, hdatalen)
				|| !EVP_DigestFinal(&mctx, digest, &digest_length))
				{
				OPENSSL_PUT_ERROR(SSL, ssl3_send_client_verify, ERR_R_EVP_LIB);
				goto err;
				}
			}
		else if (pkey->type == EVP_PKEY_RSA)
			{
			s->method->ssl3_enc->cert_verify_mac(s, NID_md5, digest);
			s->method->ssl3_enc->cert_verify_mac(s,
				NID_sha1, &digest[MD5_DIGEST_LENGTH]);
			digest_length = MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH;
			/* Using a NULL signature MD makes EVP_PKEY_sign perform
			 * a raw RSA signature, rather than wrapping in a
			 * DigestInfo. */
			md = NULL;
			}
		else if (pkey->type == EVP_PKEY_DSA || pkey->type == EVP_PKEY_EC)
			{
			s->method->ssl3_enc->cert_verify_mac(s, NID_sha1, digest);
			digest_length = SHA_DIGEST_LENGTH;
			md = EVP_sha1();
			}
		else
			{
			OPENSSL_PUT_ERROR(SSL, ssl3_send_client_verify, ERR_R_INTERNAL_ERROR);
			goto err;
			}

		/* Sign the digest. */
		pctx = EVP_PKEY_CTX_new(pkey, NULL);
		if (pctx == NULL)
			goto err;

		/* Initialize the EVP_PKEY_CTX and determine the size of the signature. */
		if (EVP_PKEY_sign_init(pctx) != 1 ||
			EVP_PKEY_CTX_set_signature_md(pctx, md) != 1 ||
			EVP_PKEY_sign(pctx, NULL, &signature_length,
				digest, digest_length) != 1)
			{
			OPENSSL_PUT_ERROR(SSL, ssl3_send_client_verify, ERR_R_EVP_LIB);
			goto err;
			}

		if (p + 2 + signature_length > buf + SSL3_RT_MAX_PLAIN_LENGTH)
			{
			OPENSSL_PUT_ERROR(SSL, ssl3_send_client_verify, SSL_R_DATA_LENGTH_TOO_LONG);
			goto err;
			}

		if (EVP_PKEY_sign(pctx, &p[2], &signature_length,
				digest, digest_length) != 1)
			{
			OPENSSL_PUT_ERROR(SSL, ssl3_send_client_verify, ERR_R_EVP_LIB);
			goto err;
			}

		s2n(signature_length, p);
		n += signature_length + 2;

		/* Now that client auth is completed, we no longer need cached
		 * handshake records and can digest them. */
		if (SSL_USE_SIGALGS(s))
			{
			if (!ssl3_digest_cached_records(s))
				goto err;
			}

		ssl_set_handshake_header(s, SSL3_MT_CERTIFICATE_VERIFY, n);
		s->state=SSL3_ST_CW_CERT_VRFY_B;
		}
	EVP_MD_CTX_cleanup(&mctx);
	EVP_PKEY_CTX_free(pctx);
	return ssl_do_write(s);
err:
	EVP_MD_CTX_cleanup(&mctx);
	EVP_PKEY_CTX_free(pctx);
	return(-1);
	}

/* Check a certificate can be used for client authentication. Currently
 * check cert exists, if we have a suitable digest for TLS 1.2 if
 * static DH client certificates can be used and optionally checks
 * suitability for Suite B.
 */
static int ssl3_check_client_certificate(SSL *s)
	{
	unsigned long alg_k;
	if (!s->cert || !s->cert->key->x509 || !s->cert->key->privatekey)
		return 0;
	/* If no suitable signature algorithm can't use certificate */
	if (SSL_USE_SIGALGS(s) && !s->cert->key->digest)
		return 0;
	/* If strict mode check suitability of chain before using it.
	 * This also adjusts suite B digest if necessary.
	 */
	if (s->cert->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT &&
		!tls1_check_chain(s, NULL, NULL, NULL, -2))
		return 0;
	alg_k=s->s3->tmp.new_cipher->algorithm_mkey;
	/* See if we can use client certificate for fixed DH */
	if (alg_k & (SSL_kDHr|SSL_kDHd))
		{
		SESS_CERT *scert = s->session->sess_cert;
		int i = scert->peer_cert_type;
		EVP_PKEY *clkey = NULL, *spkey = NULL;
		clkey = s->cert->key->privatekey;
		/* If client key not DH assume it can be used */
		if (EVP_PKEY_id(clkey) != EVP_PKEY_DH)
			return 1;
		if (i >= 0)
			spkey = X509_get_pubkey(scert->peer_pkeys[i].x509);
		if (spkey)
			{
			/* Compare server and client parameters */
			i = EVP_PKEY_cmp_parameters(clkey, spkey);
			EVP_PKEY_free(spkey);
			if (i != 1)
				return 0;
			}
		s->s3->flags |= TLS1_FLAGS_SKIP_CERT_VERIFY;
		}
	return 1;
	}

int ssl3_send_client_certificate(SSL *s)
	{
	X509 *x509=NULL;
	EVP_PKEY *pkey=NULL;
	int i;

	if (s->state ==	SSL3_ST_CW_CERT_A)
		{
		/* Let cert callback update client certificates if required */
		if (s->cert->cert_cb)
			{
			i = s->cert->cert_cb(s, s->cert->cert_cb_arg);
			if (i < 0)
				{
				s->rwstate=SSL_X509_LOOKUP;
				return -1;
				}
			if (i == 0)
				{
				ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_INTERNAL_ERROR);
				return 0;
				}
			s->rwstate=SSL_NOTHING;
			}
		if (ssl3_check_client_certificate(s))
			s->state=SSL3_ST_CW_CERT_C;
		else
			s->state=SSL3_ST_CW_CERT_B;
		}

	/* We need to get a client cert */
	if (s->state == SSL3_ST_CW_CERT_B)
		{
		/* If we get an error, we need to
		 * ssl->rwstate=SSL_X509_LOOKUP; return(-1);
		 * We then get retied later */
		i=0;
		i = ssl_do_client_cert_cb(s, &x509, &pkey);
		if (i < 0)
			{
			s->rwstate=SSL_X509_LOOKUP;
			return(-1);
			}
		s->rwstate=SSL_NOTHING;
		if ((i == 1) && (pkey != NULL) && (x509 != NULL))
			{
			s->state=SSL3_ST_CW_CERT_B;
			if (	!SSL_use_certificate(s,x509) ||
				!SSL_use_PrivateKey(s,pkey))
				i=0;
			}
		else if (i == 1)
			{
			i=0;
			OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, SSL_R_BAD_DATA_RETURNED_BY_CALLBACK);
			}

		if (x509 != NULL) X509_free(x509);
		if (pkey != NULL) EVP_PKEY_free(pkey);
		if (i && !ssl3_check_client_certificate(s))
			i = 0;
		if (i == 0)
			{
			if (s->version == SSL3_VERSION)
				{
				s->s3->tmp.cert_req=0;
				ssl3_send_alert(s,SSL3_AL_WARNING,SSL_AD_NO_CERTIFICATE);
				return(1);
				}
			else
				{
				s->s3->tmp.cert_req=2;
				}
			}

		/* Ok, we have a cert */
		s->state=SSL3_ST_CW_CERT_C;
		}

	if (s->state == SSL3_ST_CW_CERT_C)
		{
		s->state=SSL3_ST_CW_CERT_D;
		ssl3_output_cert_chain(s,
			(s->s3->tmp.cert_req == 2)?NULL:s->cert->key);
		}
	/* SSL3_ST_CW_CERT_D */
	return ssl_do_write(s);
	}

#define has_bits(i,m)	(((i)&(m)) == (m))

int ssl3_check_cert_and_algorithm(SSL *s)
	{
	int i,idx;
	long alg_k,alg_a;
	EVP_PKEY *pkey=NULL;
	SESS_CERT *sc;
	RSA *rsa;
#ifndef OPENSSL_NO_DH
	DH *dh;
#endif

	/* we don't have a certificate */
	if (!ssl_cipher_has_server_public_key(s->s3->tmp.new_cipher))
		return 1;

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

	sc=s->session->sess_cert;
	if (sc == NULL)
		{
		OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_INTERNAL_ERROR);
		goto err;
		}

	rsa=s->session->sess_cert->peer_rsa_tmp;
#ifndef OPENSSL_NO_DH
	dh=s->session->sess_cert->peer_dh_tmp;
#endif

	/* This is the passed certificate */

	idx=sc->peer_cert_type;
#ifndef OPENSSL_NO_ECDH
	if (idx == SSL_PKEY_ECC)
		{
		if (ssl_check_srvr_ecc_cert_and_alg(sc->peer_pkeys[idx].x509,
		    						s) == 0) 
			{ /* check failed */
			OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, SSL_R_BAD_ECC_CERT);
			goto f_err;
			}
		else 
			{
			return 1;
			}
		}
	else if (alg_a & SSL_aECDSA)
		{
		OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, SSL_R_MISSING_ECDSA_SIGNING_CERT);
		goto f_err;
		}
	else if (alg_k & (SSL_kECDHr|SSL_kECDHe))
		{
		OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, SSL_R_MISSING_ECDH_CERT);
		goto f_err;
		}
#endif
	pkey=X509_get_pubkey(sc->peer_pkeys[idx].x509);
	i=X509_certificate_type(sc->peer_pkeys[idx].x509,pkey);
	EVP_PKEY_free(pkey);

	
	/* Check that we have a certificate if we require one */
	if ((alg_a & SSL_aRSA) && !has_bits(i,EVP_PK_RSA|EVP_PKT_SIGN))
		{
		OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, SSL_R_MISSING_RSA_SIGNING_CERT);
		goto f_err;
		}
#ifndef OPENSSL_NO_DSA
	else if ((alg_a & SSL_aDSS) && !has_bits(i,EVP_PK_DSA|EVP_PKT_SIGN))
		{
		OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, SSL_R_MISSING_DSA_SIGNING_CERT);
		goto f_err;
		}
#endif
	if ((alg_k & SSL_kRSA) &&
		!(has_bits(i,EVP_PK_RSA|EVP_PKT_ENC) || (rsa != NULL)))
		{
		OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, SSL_R_MISSING_RSA_ENCRYPTING_CERT);
		goto f_err;
		}
#ifndef OPENSSL_NO_DH
	if ((alg_k & SSL_kEDH) && 
		!(has_bits(i,EVP_PK_DH|EVP_PKT_EXCH) || (dh != NULL)))
		{
		OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, SSL_R_MISSING_DH_KEY);
		goto f_err;
		}
	else if ((alg_k & SSL_kDHr) && !SSL_USE_SIGALGS(s) &&
		!has_bits(i,EVP_PK_DH|EVP_PKS_RSA))
		{
		OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, SSL_R_MISSING_DH_RSA_CERT);
		goto f_err;
		}
#ifndef OPENSSL_NO_DSA
	else if ((alg_k & SSL_kDHd) && !SSL_USE_SIGALGS(s) &&
		!has_bits(i,EVP_PK_DH|EVP_PKS_DSA))
		{
		OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, SSL_R_MISSING_DH_DSA_CERT);
		goto f_err;
		}
#endif
#endif

	if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && !has_bits(i,EVP_PKT_EXP))
		{
		if (alg_k & SSL_kRSA)
			{
			if (rsa == NULL
			    || RSA_size(rsa)*8 > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher))
				{
				OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, SSL_R_MISSING_EXPORT_TMP_RSA_KEY);
				goto f_err;
				}
			}
		else
#ifndef OPENSSL_NO_DH
			if (alg_k & (SSL_kEDH|SSL_kDHr|SSL_kDHd))
			    {
			    if (dh == NULL
				|| DH_size(dh)*8 > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher))
				{
				OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, SSL_R_MISSING_EXPORT_TMP_DH_KEY);
				goto f_err;
				}
			}
		else
#endif
			{
			OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE);
			goto f_err;
			}
		}
	return(1);
f_err:
	ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);
err:
	return(0);
	}

# if !defined(OPENSSL_NO_NEXTPROTONEG)
int ssl3_send_next_proto(SSL *s)
	{
	unsigned int len, padding_len;
	unsigned char *d;

	if (s->state == SSL3_ST_CW_NEXT_PROTO_A)
		{
		len = s->next_proto_negotiated_len;
		padding_len = 32 - ((len + 2) % 32);
		d = (unsigned char *)s->init_buf->data;
		d[4] = len;
		memcpy(d + 5, s->next_proto_negotiated, len);
		d[5 + len] = padding_len;
		memset(d + 6 + len, 0, padding_len);
		*(d++)=SSL3_MT_NEXT_PROTO;
		l2n3(2 + len + padding_len, d);
		s->state = SSL3_ST_CW_NEXT_PROTO_B;
		s->init_num = 4 + 2 + len + padding_len;
		s->init_off = 0;
		}

	return ssl3_do_write(s, SSL3_RT_HANDSHAKE);
}

# endif  /* !OPENSSL_NO_NEXTPROTONEG */

int ssl3_send_channel_id(SSL *s)
	{
	unsigned char *d;
	int ret = -1, public_key_len;
	EVP_MD_CTX md_ctx;
	size_t sig_len;
	ECDSA_SIG *sig = NULL;
	unsigned char *public_key = NULL, *derp, *der_sig = NULL;

	if (s->state != SSL3_ST_CW_CHANNEL_ID_A)
		return ssl3_do_write(s, SSL3_RT_HANDSHAKE);

	if (!s->tlsext_channel_id_private && s->ctx->channel_id_cb)
		{
		EVP_PKEY *key = NULL;
		s->ctx->channel_id_cb(s, &key);
		if (key != NULL)
			{
			s->tlsext_channel_id_private = key;
			}
		}
	if (!s->tlsext_channel_id_private)
		{
		s->rwstate=SSL_CHANNEL_ID_LOOKUP;
		return (-1);
		}
	s->rwstate=SSL_NOTHING;

	d = (unsigned char *)s->init_buf->data;
	*(d++)=SSL3_MT_ENCRYPTED_EXTENSIONS;
	l2n3(2 + 2 + TLSEXT_CHANNEL_ID_SIZE, d);
	if (s->s3->tlsext_channel_id_new)
		s2n(TLSEXT_TYPE_channel_id_new, d);
	else
		s2n(TLSEXT_TYPE_channel_id, d);
	s2n(TLSEXT_CHANNEL_ID_SIZE, d);

	EVP_MD_CTX_init(&md_ctx);

	public_key_len = i2d_PublicKey(s->tlsext_channel_id_private, NULL);
	if (public_key_len <= 0)
		{
		OPENSSL_PUT_ERROR(SSL, ssl3_send_channel_id, SSL_R_CANNOT_SERIALIZE_PUBLIC_KEY);
		goto err;
		}
	/* i2d_PublicKey will produce an ANSI X9.62 public key which, for a
	 * P-256 key, is 0x04 (meaning uncompressed) followed by the x and y
	 * field elements as 32-byte, big-endian numbers. */
	if (public_key_len != 65)
		{
		OPENSSL_PUT_ERROR(SSL, ssl3_send_channel_id, SSL_R_CHANNEL_ID_NOT_P256);
		goto err;
		}
	public_key = OPENSSL_malloc(public_key_len);
	if (!public_key)
		{
		OPENSSL_PUT_ERROR(SSL, ssl3_send_channel_id, ERR_R_MALLOC_FAILURE);
		goto err;
		}

	derp = public_key;
	i2d_PublicKey(s->tlsext_channel_id_private, &derp);

	if (EVP_DigestSignInit(&md_ctx, NULL, EVP_sha256(), NULL,
			       s->tlsext_channel_id_private) != 1)
		{
		OPENSSL_PUT_ERROR(SSL, ssl3_send_channel_id, SSL_R_EVP_DIGESTSIGNINIT_FAILED);
		goto err;
		}

	if (!tls1_channel_id_hash(&md_ctx, s))
		goto err;

	if (!EVP_DigestSignFinal(&md_ctx, NULL, &sig_len))
		{
		OPENSSL_PUT_ERROR(SSL, ssl3_send_channel_id, SSL_R_EVP_DIGESTSIGNFINAL_FAILED);
		goto err;
		}

	der_sig = OPENSSL_malloc(sig_len);
	if (!der_sig)
		{
		OPENSSL_PUT_ERROR(SSL, ssl3_send_channel_id, ERR_R_MALLOC_FAILURE);
		goto err;
		}

	if (!EVP_DigestSignFinal(&md_ctx, der_sig, &sig_len))
		{
		OPENSSL_PUT_ERROR(SSL, ssl3_send_channel_id, SSL_R_EVP_DIGESTSIGNFINAL_FAILED);
		goto err;
		}

	derp = der_sig;
	sig = d2i_ECDSA_SIG(NULL, (const unsigned char**) &derp, sig_len);
	if (sig == NULL)
		{
		OPENSSL_PUT_ERROR(SSL, ssl3_send_channel_id, SSL_R_D2I_ECDSA_SIG);
		goto err;
		}

	/* The first byte of public_key will be 0x4, denoting an uncompressed key. */
	memcpy(d, public_key + 1, 64);
	d += 64;
	memset(d, 0, 2 * 32);
	BN_bn2bin(sig->r, d + 32 - BN_num_bytes(sig->r));
	d += 32;
	BN_bn2bin(sig->s, d + 32 - BN_num_bytes(sig->s));
	d += 32;

	s->state = SSL3_ST_CW_CHANNEL_ID_B;
	s->init_num = 4 + 2 + 2 + TLSEXT_CHANNEL_ID_SIZE;
	s->init_off = 0;

	ret = ssl3_do_write(s, SSL3_RT_HANDSHAKE);

err:
	EVP_MD_CTX_cleanup(&md_ctx);
	if (public_key)
		OPENSSL_free(public_key);
	if (der_sig)
		OPENSSL_free(der_sig);
	if (sig)
		ECDSA_SIG_free(sig);

	return ret;
	}

int ssl_do_client_cert_cb(SSL *s, X509 **px509, EVP_PKEY **ppkey)
	{
	int i = 0;
        /* TODO(fork): remove */
#if 0
#ifndef OPENSSL_NO_ENGINE
	if (s->ctx->client_cert_engine)
		{
		i = ENGINE_load_ssl_client_cert(s->ctx->client_cert_engine, s,
						SSL_get_client_CA_list(s),
						px509, ppkey, NULL, NULL, NULL);
		if (i != 0)
			return i;
		}
#endif
#endif
	if (s->ctx->client_cert_cb)
		i = s->ctx->client_cert_cb(s,px509,ppkey);
	return i;
	}
