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

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

#include <openssl/bytestring.h>
#include <openssl/evp.h>
#include <openssl/hmac.h>
#include <openssl/mem.h>
#include <openssl/obj.h>
#include <openssl/rand.h>

#include "ssl_locl.h"
static int tls_decrypt_ticket(SSL *s, const unsigned char *tick, int ticklen,
				const unsigned char *sess_id, int sesslen,
				SSL_SESSION **psess);
static int ssl_check_clienthello_tlsext(SSL *s);
static int ssl_check_serverhello_tlsext(SSL *s);

SSL3_ENC_METHOD TLSv1_enc_data={
	tls1_enc,
	tls1_mac,
	tls1_setup_key_block,
	tls1_generate_master_secret,
	tls1_change_cipher_state,
	tls1_final_finish_mac,
	TLS1_FINISH_MAC_LENGTH,
	tls1_cert_verify_mac,
	TLS_MD_CLIENT_FINISH_CONST,TLS_MD_CLIENT_FINISH_CONST_SIZE,
	TLS_MD_SERVER_FINISH_CONST,TLS_MD_SERVER_FINISH_CONST_SIZE,
	tls1_alert_code,
	tls1_export_keying_material,
	0,
	SSL3_HM_HEADER_LENGTH,
	ssl3_set_handshake_header,
	ssl3_handshake_write
	};

SSL3_ENC_METHOD TLSv1_1_enc_data={
	tls1_enc,
	tls1_mac,
	tls1_setup_key_block,
	tls1_generate_master_secret,
	tls1_change_cipher_state,
	tls1_final_finish_mac,
	TLS1_FINISH_MAC_LENGTH,
	tls1_cert_verify_mac,
	TLS_MD_CLIENT_FINISH_CONST,TLS_MD_CLIENT_FINISH_CONST_SIZE,
	TLS_MD_SERVER_FINISH_CONST,TLS_MD_SERVER_FINISH_CONST_SIZE,
	tls1_alert_code,
	tls1_export_keying_material,
	SSL_ENC_FLAG_EXPLICIT_IV,
	SSL3_HM_HEADER_LENGTH,
	ssl3_set_handshake_header,
	ssl3_handshake_write
	};

SSL3_ENC_METHOD TLSv1_2_enc_data={
	tls1_enc,
	tls1_mac,
	tls1_setup_key_block,
	tls1_generate_master_secret,
	tls1_change_cipher_state,
	tls1_final_finish_mac,
	TLS1_FINISH_MAC_LENGTH,
	tls1_cert_verify_mac,
	TLS_MD_CLIENT_FINISH_CONST,TLS_MD_CLIENT_FINISH_CONST_SIZE,
	TLS_MD_SERVER_FINISH_CONST,TLS_MD_SERVER_FINISH_CONST_SIZE,
	tls1_alert_code,
	tls1_export_keying_material,
	SSL_ENC_FLAG_EXPLICIT_IV|SSL_ENC_FLAG_SIGALGS|SSL_ENC_FLAG_SHA256_PRF
		|SSL_ENC_FLAG_TLS1_2_CIPHERS,
	SSL3_HM_HEADER_LENGTH,
	ssl3_set_handshake_header,
	ssl3_handshake_write
	};

static int compare_uint16_t(const void *p1, const void *p2)
	{
	uint16_t u1 = *((const uint16_t*)p1);
	uint16_t u2 = *((const uint16_t*)p2);
	if (u1 < u2)
		{
		return -1;
		}
	else if (u1 > u2)
		{
		return 1;
		}
	else
		{
		return 0;
		}
	}

/* Per http://tools.ietf.org/html/rfc5246#section-7.4.1.4, there may not be more
 * than one extension of the same type in a ClientHello or ServerHello. This
 * function does an initial scan over the extensions block to filter those
 * out. */
static int tls1_check_duplicate_extensions(const CBS *cbs)
	{
	CBS extensions = *cbs;
	size_t num_extensions = 0, i = 0;
	uint16_t *extension_types = NULL;
	int ret = 0;

	/* First pass: count the extensions. */
	while (CBS_len(&extensions) > 0)
		{
		uint16_t type;
		CBS extension;

		if (!CBS_get_u16(&extensions, &type) ||
			!CBS_get_u16_length_prefixed(&extensions, &extension))
			{
			goto done;
			}

		num_extensions++;
		}

	if (num_extensions == 0)
		{
		return 1;
		}

	extension_types = (uint16_t*)OPENSSL_malloc(sizeof(uint16_t) * num_extensions);
	if (extension_types == NULL)
		{
		OPENSSL_PUT_ERROR(SSL, tls1_check_duplicate_extensions, ERR_R_MALLOC_FAILURE);
		goto done;
		}

	/* Second pass: gather the extension types. */
	extensions = *cbs;
	for (i = 0; i < num_extensions; i++)
		{
		CBS extension;

		if (!CBS_get_u16(&extensions, &extension_types[i]) ||
			!CBS_get_u16_length_prefixed(&extensions, &extension))
			{
			/* This should not happen. */
			goto done;
			}
		}
	assert(CBS_len(&extensions) == 0);

	/* Sort the extensions and make sure there are no duplicates. */
	qsort(extension_types, num_extensions, sizeof(uint16_t), compare_uint16_t);
	for (i = 1; i < num_extensions; i++)
		{
		if (extension_types[i-1] == extension_types[i])
			{
			goto done;
			}
		}

	ret = 1;
done:
	if (extension_types)
		OPENSSL_free(extension_types);
	return ret;
	}

char ssl_early_callback_init(struct ssl_early_callback_ctx *ctx)
	{
	CBS client_hello, session_id, cipher_suites, compression_methods, extensions;

	CBS_init(&client_hello, ctx->client_hello, ctx->client_hello_len);

	/* Skip client version. */
	if (!CBS_skip(&client_hello, 2))
		return 0;

	/* Skip client nonce. */
	if (!CBS_skip(&client_hello, 32))
		return 0;

	/* Extract session_id. */
	if (!CBS_get_u8_length_prefixed(&client_hello, &session_id))
		return 0;
	ctx->session_id = CBS_data(&session_id);
	ctx->session_id_len = CBS_len(&session_id);

	/* Skip past DTLS cookie */
	if (SSL_IS_DTLS(ctx->ssl))
		{
		CBS cookie;

		if (!CBS_get_u8_length_prefixed(&client_hello, &cookie))
			return 0;
		}

	/* Extract cipher_suites. */
	if (!CBS_get_u16_length_prefixed(&client_hello, &cipher_suites) ||
		CBS_len(&cipher_suites) < 2 ||
		(CBS_len(&cipher_suites) & 1) != 0)
		return 0;
	ctx->cipher_suites = CBS_data(&cipher_suites);
	ctx->cipher_suites_len = CBS_len(&cipher_suites);

	/* Extract compression_methods. */
	if (!CBS_get_u8_length_prefixed(&client_hello, &compression_methods) ||
		CBS_len(&compression_methods) < 1)
		return 0;
	ctx->compression_methods = CBS_data(&compression_methods);
	ctx->compression_methods_len = CBS_len(&compression_methods);

	/* If the ClientHello ends here then it's valid, but doesn't have any
	 * extensions. (E.g. SSLv3.) */
	if (CBS_len(&client_hello) == 0)
		{
		ctx->extensions = NULL;
		ctx->extensions_len = 0;
		return 1;
		}

	/* Extract extensions and check it is valid. */
	if (!CBS_get_u16_length_prefixed(&client_hello, &extensions) ||
		!tls1_check_duplicate_extensions(&extensions) ||
		CBS_len(&client_hello) != 0)
		return 0;
	ctx->extensions = CBS_data(&extensions);
	ctx->extensions_len = CBS_len(&extensions);

	return 1;
	}

char
SSL_early_callback_ctx_extension_get(const struct ssl_early_callback_ctx *ctx,
				     uint16_t extension_type,
				     const unsigned char **out_data,
				     size_t *out_len)
	{
	CBS extensions;

	CBS_init(&extensions, ctx->extensions, ctx->extensions_len);

	while (CBS_len(&extensions) != 0)
		{
		uint16_t type;
		CBS extension;

		/* Decode the next extension. */
		if (!CBS_get_u16(&extensions, &type) ||
			!CBS_get_u16_length_prefixed(&extensions, &extension))
			return 0;

		if (type == extension_type)
			{
			*out_data = CBS_data(&extension);
			*out_len = CBS_len(&extension);
			return 1;
			}
		}

	return 0;
	}


static const int nid_list[] =
	{
		NID_sect163k1, /* sect163k1 (1) */
		NID_sect163r1, /* sect163r1 (2) */
		NID_sect163r2, /* sect163r2 (3) */
		NID_sect193r1, /* sect193r1 (4) */ 
		NID_sect193r2, /* sect193r2 (5) */ 
		NID_sect233k1, /* sect233k1 (6) */
		NID_sect233r1, /* sect233r1 (7) */ 
		NID_sect239k1, /* sect239k1 (8) */ 
		NID_sect283k1, /* sect283k1 (9) */
		NID_sect283r1, /* sect283r1 (10) */ 
		NID_sect409k1, /* sect409k1 (11) */ 
		NID_sect409r1, /* sect409r1 (12) */
		NID_sect571k1, /* sect571k1 (13) */ 
		NID_sect571r1, /* sect571r1 (14) */ 
		NID_secp160k1, /* secp160k1 (15) */
		NID_secp160r1, /* secp160r1 (16) */ 
		NID_secp160r2, /* secp160r2 (17) */ 
		NID_secp192k1, /* secp192k1 (18) */
		NID_X9_62_prime192v1, /* secp192r1 (19) */ 
		NID_secp224k1, /* secp224k1 (20) */ 
		NID_secp224r1, /* secp224r1 (21) */
		NID_secp256k1, /* secp256k1 (22) */ 
		NID_X9_62_prime256v1, /* secp256r1 (23) */ 
		NID_secp384r1, /* secp384r1 (24) */
		NID_secp521r1,  /* secp521r1 (25) */	
		NID_brainpoolP256r1,  /* brainpoolP256r1 (26) */	
		NID_brainpoolP384r1,  /* brainpoolP384r1 (27) */	
		NID_brainpoolP512r1  /* brainpool512r1 (28) */	
	};

static const uint8_t ecformats_default[] =
	{
	TLSEXT_ECPOINTFORMAT_uncompressed,
	};

static const uint16_t eccurves_default[] =
	{
		23, /* secp256r1 (23) */
		24, /* secp384r1 (24) */
		25, /* secp521r1 (25) */
	};

int tls1_ec_curve_id2nid(uint16_t curve_id)
	{
	/* ECC curves from draft-ietf-tls-ecc-12.txt (Oct. 17, 2005) */
	if (curve_id < 1 || curve_id > sizeof(nid_list)/sizeof(nid_list[0]))
		return OBJ_undef;
	return nid_list[curve_id-1];
	}

uint16_t tls1_ec_nid2curve_id(int nid)
	{
	size_t i;
	for (i = 0; i < sizeof(nid_list)/sizeof(nid_list[0]); i++)
		{
		/* nid_list[i] stores the NID corresponding to curve ID i+1. */
		if (nid == nid_list[i])
			return i + 1;
		}
	/* Use 0 for non-existent curve ID. Note: this assumes that curve ID 0
	 * will never be allocated. */
	return 0;
	}

/* tls1_get_curvelist sets |*out_curve_ids| and |*out_curve_ids_len| to the list
 * of allowed curve IDs. If |get_client_curves| is non-zero, return the client
 * curve list. Otherwise, return the preferred list. */
static void tls1_get_curvelist(SSL *s, int get_client_curves,
	const uint16_t **out_curve_ids, size_t *out_curve_ids_len)
	{
	if (get_client_curves)
		{
		*out_curve_ids = s->session->tlsext_ellipticcurvelist;
		*out_curve_ids_len = s->session->tlsext_ellipticcurvelist_length;
		return;
		}

	*out_curve_ids = s->tlsext_ellipticcurvelist;
	*out_curve_ids_len = s->tlsext_ellipticcurvelist_length;
	if (!*out_curve_ids)
		{
		*out_curve_ids = eccurves_default;
		*out_curve_ids_len = sizeof(eccurves_default) / sizeof(eccurves_default[0]);
		}
	}

int tls1_check_curve(SSL *s, CBS *cbs, uint16_t *out_curve_id)
	{
	uint8_t curve_type;
	uint16_t curve_id;
	const uint16_t *curves;
	size_t curves_len, i;

	/* Only support named curves. */
	if (!CBS_get_u8(cbs, &curve_type) ||
		curve_type != NAMED_CURVE_TYPE ||
		!CBS_get_u16(cbs, &curve_id))
		return 0;

	tls1_get_curvelist(s, 0, &curves, &curves_len);
	for (i = 0; i < curves_len; i++)
		{
		if (curve_id == curves[i])
			{
			*out_curve_id = curve_id;
			return 1;
			}
		}
	return 0;
	}

int tls1_get_shared_curve(SSL *s)
	{
	const uint16_t *pref, *supp;
	size_t preflen, supplen, i, j;

	/* Can't do anything on client side */
	if (s->server == 0)
		return NID_undef;

	/* Return first preference shared curve */
	tls1_get_curvelist(s, !!(s->options & SSL_OP_CIPHER_SERVER_PREFERENCE),
				&supp, &supplen);
	tls1_get_curvelist(s, !(s->options & SSL_OP_CIPHER_SERVER_PREFERENCE),
				&pref, &preflen);
	for (i = 0; i < preflen; i++)
		{
		for (j = 0; j < supplen; j++)
			{
			if (pref[i] == supp[j])
				return tls1_ec_curve_id2nid(pref[i]);
			}
		}
	return NID_undef;
	}

/* NOTE: tls1_ec_curve_id2nid and tls1_set_curves assume that
 *
 * (a) 0 is not a valid curve ID.
 *
 * (b) The largest curve ID is 31.
 *
 * Those implementations must be revised before adding support for curve IDs
 * that break these assumptions. */
OPENSSL_COMPILE_ASSERT(
	(sizeof(nid_list) / sizeof(nid_list[0])) < 32, small_curve_ids);

int tls1_set_curves(uint16_t **out_curve_ids, size_t *out_curve_ids_len,
	const int *curves, size_t ncurves)
	{
	uint16_t *curve_ids;
	size_t i;
	/* Bitmap of curves included to detect duplicates: only works
	 * while curve ids < 32 
	 */
	uint32_t dup_list = 0;
	curve_ids = (uint16_t*)OPENSSL_malloc(ncurves * sizeof(uint16_t));
	if (!curve_ids)
		return 0;
	for (i = 0; i < ncurves; i++)
		{
		uint32_t idmask;
		uint16_t id;
		id = tls1_ec_nid2curve_id(curves[i]);
		idmask = ((uint32_t)1) << id;
		if (!id || (dup_list & idmask))
			{
			OPENSSL_free(curve_ids);
			return 0;
			}
		dup_list |= idmask;
		curve_ids[i] = id;
		}
	if (*out_curve_ids)
		OPENSSL_free(*out_curve_ids);
	*out_curve_ids = curve_ids;
	*out_curve_ids_len = ncurves;
	return 1;
	}

/* tls1_curve_params_from_ec_key sets |*out_curve_id| and |*out_comp_id| to the
 * TLS curve ID and point format, respectively, for |ec|. It returns one on
 * success and zero on failure. */
static int tls1_curve_params_from_ec_key(uint16_t *out_curve_id, uint8_t *out_comp_id, EC_KEY *ec)
	{
	int nid;
	uint16_t id;
	const EC_GROUP *grp;
	if (!ec)
		return 0;

	grp = EC_KEY_get0_group(ec);
	if (!grp)
		return 0;

	/* Determine curve ID */
	nid = EC_GROUP_get_curve_name(grp);
	id = tls1_ec_nid2curve_id(nid);
	if (!id)
		return 0;

	/* Set the named curve ID. Arbitrary explicit curves are not
	 * supported. */
	*out_curve_id = id;

	if (out_comp_id)
		{
        	if (EC_KEY_get0_public_key(ec) == NULL)
			return 0;
		if (EC_KEY_get_conv_form(ec) == POINT_CONVERSION_COMPRESSED)
			*out_comp_id = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime;
		else
			*out_comp_id = TLSEXT_ECPOINTFORMAT_uncompressed;
		}
	return 1;
	}

/* Check an EC key is compatible with extensions */
static int tls1_check_ec_key(SSL *s,
	const uint16_t *curve_id, const uint8_t *comp_id)
	{
	const uint16_t *curves;
	size_t curves_len, i;
	int j;
	/* If point formats extension present check it, otherwise everything
	 * is supported (see RFC4492).
	 */
	if (comp_id && s->session->tlsext_ecpointformatlist)
		{
		uint8_t *p = s->session->tlsext_ecpointformatlist;
		size_t plen = s->session->tlsext_ecpointformatlist_length;
		for (i = 0; i < plen; i++)
			{
			if (*comp_id == p[i])
				break;
			}
		if (i == plen)
			return 0;
		}
	if (!curve_id)
		return 1;
	/* Check curve is consistent with client and server preferences */
	for (j = 0; j <= 1; j++)
		{
		tls1_get_curvelist(s, j, &curves, &curves_len);
		for (i = 0; i < curves_len; i++)
			{
			if (curves[i] == *curve_id)
				break;
			}
		if (i == curves_len)
			return 0;
		/* For clients can only check sent curve list */
		if (!s->server)
			return 1;
		}
	return 1;
	}

static void tls1_get_formatlist(SSL *s, const unsigned char **pformats,
					size_t *pformatslen)
	{
	/* If we have a custom point format list use it otherwise
	 * use default */
	if (s->tlsext_ecpointformatlist)
		{
		*pformats = s->tlsext_ecpointformatlist;
		*pformatslen = s->tlsext_ecpointformatlist_length;
		}
	else
		{
		*pformats = ecformats_default;
		*pformatslen = sizeof(ecformats_default);
		}
	}

/* Check cert parameters compatible with extensions: currently just checks
 * EC certificates have compatible curves and compression.
 */
static int tls1_check_cert_param(SSL *s, X509 *x, int set_ee_md)
	{
	uint8_t comp_id;
	uint16_t curve_id;
	EVP_PKEY *pkey;
	int rv;
	pkey = X509_get_pubkey(x);
	if (!pkey)
		return 0;
	/* If not EC nothing to do */
	if (pkey->type != EVP_PKEY_EC)
		{
		EVP_PKEY_free(pkey);
		return 1;
		}
	rv = tls1_curve_params_from_ec_key(&curve_id, &comp_id, pkey->pkey.ec);
	EVP_PKEY_free(pkey);
	if (!rv)
		return 0;
	/* Can't check curve_id for client certs as we don't have a
	 * supported curves extension.
	 */
	return tls1_check_ec_key(s, s->server ? &curve_id : NULL, &comp_id);
	}
/* Check EC temporary key is compatible with client extensions */
int tls1_check_ec_tmp_key(SSL *s, unsigned long cid)
	{
	uint16_t curve_id;
	EC_KEY *ec = s->cert->ecdh_tmp;
#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL
	/* Allow any curve: not just those peer supports */
	if (s->cert->cert_flags & SSL_CERT_FLAG_BROKEN_PROTOCOL)
		return 1;
#endif
	if (s->cert->ecdh_tmp_auto)
		{
		/* Need a shared curve */
		return tls1_get_shared_curve(s) != NID_undef;
		}
	if (!ec)
		{
		if (s->cert->ecdh_tmp_cb)
			return 1;
		else
			return 0;
		}
	if (!tls1_curve_params_from_ec_key(&curve_id, NULL, ec))
		return 0;
/* Set this to allow use of invalid curves for testing */
#if 0
	return 1;
#else
	return tls1_check_ec_key(s, &curve_id, NULL);
#endif
	}



/* List of supported signature algorithms and hashes. Should make this
 * customisable at some point, for now include everything we support.
 */

#define tlsext_sigalg_rsa(md) md, TLSEXT_signature_rsa,

#define tlsext_sigalg_ecdsa(md) md, TLSEXT_signature_ecdsa,

#define tlsext_sigalg(md) \
		tlsext_sigalg_rsa(md) \
		tlsext_sigalg_ecdsa(md)

static const uint8_t tls12_sigalgs[] = {
	tlsext_sigalg(TLSEXT_hash_sha512)
	tlsext_sigalg(TLSEXT_hash_sha384)
	tlsext_sigalg(TLSEXT_hash_sha256)
	tlsext_sigalg(TLSEXT_hash_sha224)
	tlsext_sigalg(TLSEXT_hash_sha1)
};
size_t tls12_get_psigalgs(SSL *s, const unsigned char **psigs)
	{
	/* If server use client authentication sigalgs if not NULL */
	if (s->server && s->cert->client_sigalgs)
		{
		*psigs = s->cert->client_sigalgs;
		return s->cert->client_sigalgslen;
		}
	else if (s->cert->conf_sigalgs)
		{
		*psigs = s->cert->conf_sigalgs;
		return s->cert->conf_sigalgslen;
		}
	else
		{
		*psigs = tls12_sigalgs;
		return sizeof(tls12_sigalgs);
		}
	}

/* tls12_check_peer_sigalg parses a SignatureAndHashAlgorithm out of
 * |cbs|. It checks it is consistent with |s|'s sent supported
 * signature algorithms and, if so, writes the relevant digest into
 * |*out_md| and returns 1. Otherwise it returns 0 and writes an alert
 * into |*out_alert|.
 */
int tls12_check_peer_sigalg(const EVP_MD **out_md, int *out_alert,
	SSL *s, CBS *cbs, EVP_PKEY *pkey)
	{
	const unsigned char *sent_sigs;
	size_t sent_sigslen, i;
	int sigalg = tls12_get_sigid(pkey);
	uint8_t hash, signature;
	/* Should never happen */
	if (sigalg == -1)
		{
		OPENSSL_PUT_ERROR(SSL, tls12_check_peer_sigalg, ERR_R_INTERNAL_ERROR);
		*out_alert = SSL_AD_INTERNAL_ERROR;
		return 0;
		}
	if (!CBS_get_u8(cbs, &hash) ||
		!CBS_get_u8(cbs, &signature))
		{
		OPENSSL_PUT_ERROR(SSL, tls12_check_peer_sigalg, SSL_R_DECODE_ERROR);
		*out_alert = SSL_AD_DECODE_ERROR;
		return 0;
		}
	/* Check key type is consistent with signature */
	if (sigalg != signature)
		{
		OPENSSL_PUT_ERROR(SSL, tls12_check_peer_sigalg, SSL_R_WRONG_SIGNATURE_TYPE);
		*out_alert = SSL_AD_ILLEGAL_PARAMETER;
		return 0;
		}
	if (pkey->type == EVP_PKEY_EC)
		{
		uint16_t curve_id;
		uint8_t comp_id;
		/* Check compression and curve matches extensions */
		if (!tls1_curve_params_from_ec_key(&curve_id, &comp_id, pkey->pkey.ec))
			{
			*out_alert = SSL_AD_INTERNAL_ERROR;
			return 0;
			}
		if (!s->server && !tls1_check_ec_key(s, &curve_id, &comp_id))
			{
			OPENSSL_PUT_ERROR(SSL, tls12_check_peer_sigalg, SSL_R_WRONG_CURVE);
			*out_alert = SSL_AD_ILLEGAL_PARAMETER;
			return 0;
			}
		}

	/* Check signature matches a type we sent */
	sent_sigslen = tls12_get_psigalgs(s, &sent_sigs);
	for (i = 0; i < sent_sigslen; i+=2, sent_sigs+=2)
		{
		if (hash == sent_sigs[0] && signature == sent_sigs[1])
			break;
		}
	/* Allow fallback to SHA1 if not strict mode */
	if (i == sent_sigslen && (hash != TLSEXT_hash_sha1 || s->cert->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT))
		{
		OPENSSL_PUT_ERROR(SSL, tls12_check_peer_sigalg, SSL_R_WRONG_SIGNATURE_TYPE);
		*out_alert = SSL_AD_ILLEGAL_PARAMETER;
		return 0;
		}
	*out_md = tls12_get_hash(hash);
	if (*out_md == NULL)
		{
		OPENSSL_PUT_ERROR(SSL, tls12_check_peer_sigalg, SSL_R_UNKNOWN_DIGEST);
		*out_alert = SSL_AD_ILLEGAL_PARAMETER;
		return 0;
		}
	/* Store the digest used so applications can retrieve it if they
	 * wish.
	 */
	if (s->session && s->session->sess_cert)
		s->session->sess_cert->peer_key->digest = *out_md;
	return 1;
	}
/* Get a mask of disabled algorithms: an algorithm is disabled
 * if it isn't supported or doesn't appear in supported signature
 * algorithms. Unlike ssl_cipher_get_disabled this applies to a specific
 * session and not global settings.
 * 
 */
void ssl_set_client_disabled(SSL *s)
	{
	CERT *c = s->cert;
	const unsigned char *sigalgs;
	size_t i, sigalgslen;
	int have_rsa = 0, have_ecdsa = 0;
	c->mask_a = 0;
	c->mask_k = 0;
	/* Don't allow TLS 1.2 only ciphers if we don't suppport them */
	if (!SSL_CLIENT_USE_TLS1_2_CIPHERS(s))
		c->mask_ssl = SSL_TLSV1_2;
	else
		c->mask_ssl = 0;
	/* Now go through all signature algorithms seeing if we support
	 * any for RSA, DSA, ECDSA. Do this for all versions not just
	 * TLS 1.2.
	 */
	sigalgslen = tls12_get_psigalgs(s, &sigalgs);
	for (i = 0; i < sigalgslen; i += 2, sigalgs += 2)
		{
		switch(sigalgs[1])
			{
		case TLSEXT_signature_rsa:
			have_rsa = 1;
			break;
		case TLSEXT_signature_ecdsa:
			have_ecdsa = 1;
			break;
			}
		}
	/* Disable auth if we don't include any appropriate signature
	 * algorithms.
	 */
	if (!have_rsa)
		{
		c->mask_a |= SSL_aRSA;
		}
	if (!have_ecdsa)
		{
		c->mask_a |= SSL_aECDSA;
		}
	/* with PSK there must be client callback set */
	if (!s->psk_client_callback)
		{
		c->mask_a |= SSL_aPSK;
		c->mask_k |= SSL_kPSK;
		}
	c->valid = 1;
	}

/* header_len is the length of the ClientHello header written so far, used to
 * compute padding. It does not include the record header. Pass 0 if no padding
 * is to be done. */
unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, unsigned char *limit, size_t header_len)
	{
	int extdatalen=0;
	unsigned char *ret = buf;
	unsigned char *orig = buf;
	/* See if we support any ECC ciphersuites */
	int using_ecc = 0;
	if (s->version >= TLS1_VERSION || SSL_IS_DTLS(s))
		{
		int i;
		unsigned long alg_k, alg_a;
		STACK_OF(SSL_CIPHER) *cipher_stack = SSL_get_ciphers(s);

		for (i = 0; i < sk_SSL_CIPHER_num(cipher_stack); i++)
			{
			const SSL_CIPHER *c = sk_SSL_CIPHER_value(cipher_stack, i);

			alg_k = c->algorithm_mkey;
			alg_a = c->algorithm_auth;
			if ((alg_k & SSL_kEECDH) || (alg_a & SSL_aECDSA))
				{
				using_ecc = 1;
				break;
				}
			}
		}

	/* don't add extensions for SSLv3 unless doing secure renegotiation */
	if (s->client_version == SSL3_VERSION
					&& !s->s3->send_connection_binding)
		return orig;

	ret+=2;

	if (ret>=limit) return NULL; /* this really never occurs, but ... */

 	if (s->tlsext_hostname != NULL)
		{ 
		/* Add TLS extension servername to the Client Hello message */
		unsigned long size_str;
		long lenmax; 

		/* check for enough space.
		   4 for the servername type and entension length
		   2 for servernamelist length
		   1 for the hostname type
		   2 for hostname length
		   + hostname length 
		*/
		   
		if ((lenmax = limit - ret - 9) < 0 
		    || (size_str = strlen(s->tlsext_hostname)) > (unsigned long)lenmax) 
			return NULL;
			
		/* extension type and length */
		s2n(TLSEXT_TYPE_server_name,ret); 
		s2n(size_str+5,ret);
		
		/* length of servername list */
		s2n(size_str+3,ret);
	
		/* hostname type, length and hostname */
		*(ret++) = (unsigned char) TLSEXT_NAMETYPE_host_name;
		s2n(size_str,ret);
		memcpy(ret, s->tlsext_hostname, size_str);
		ret+=size_str;
		}

        /* Add RI if renegotiating */
        if (s->renegotiate)
          {
          int el;
          
          if(!ssl_add_clienthello_renegotiate_ext(s, 0, &el, 0))
              {
              OPENSSL_PUT_ERROR(SSL, ssl_add_clienthello_tlsext, ERR_R_INTERNAL_ERROR);
              return NULL;
              }

          if((limit - ret - 4 - el) < 0) return NULL;
          
          s2n(TLSEXT_TYPE_renegotiate,ret);
          s2n(el,ret);

          if(!ssl_add_clienthello_renegotiate_ext(s, ret, &el, el))
              {
              OPENSSL_PUT_ERROR(SSL, ssl_add_clienthello_tlsext, ERR_R_INTERNAL_ERROR);
              return NULL;
              }

          ret += el;
        }

	if (!(SSL_get_options(s) & SSL_OP_NO_TICKET))
		{
		int ticklen;
		if (!s->new_session && s->session && s->session->tlsext_tick)
			ticklen = s->session->tlsext_ticklen;
		else if (s->session && s->tlsext_session_ticket &&
			 s->tlsext_session_ticket->data)
			{
			s->session->tlsext_tick = BUF_memdup(
			       s->tlsext_session_ticket->data,
			       s->tlsext_session_ticket->length);
			if (!s->session->tlsext_tick)
				return NULL;
			ticklen = s->tlsext_session_ticket->length;
			s->session->tlsext_ticklen = ticklen;
			}
		else
			ticklen = 0;
		if (ticklen == 0 && s->tlsext_session_ticket &&
		    s->tlsext_session_ticket->data == NULL)
			goto skip_ext;
		/* Check for enough room 2 for extension type, 2 for len
 		 * rest for ticket
  		 */
		if ((long)(limit - ret - 4 - ticklen) < 0) return NULL;
		s2n(TLSEXT_TYPE_session_ticket,ret); 
		s2n(ticklen,ret);
		if (ticklen)
			{
			memcpy(ret, s->session->tlsext_tick, ticklen);
			ret += ticklen;
			}
		}
		skip_ext:

	if (SSL_USE_SIGALGS(s))
		{
		size_t salglen;
		const unsigned char *salg;
		salglen = tls12_get_psigalgs(s, &salg);
		if ((size_t)(limit - ret) < salglen + 6)
			return NULL; 
		s2n(TLSEXT_TYPE_signature_algorithms,ret);
		s2n(salglen + 2, ret);
		s2n(salglen, ret);
		memcpy(ret, salg, salglen);
		ret += salglen;
		}

	if (s->ocsp_stapling_enabled)
		{
		/* The status_request extension is excessively extensible at
		 * every layer. On the client, only support requesting OCSP
		 * responses with an empty responder_id_list and no
		 * extensions. */
		if (limit - ret - 4 - 1 - 2 - 2 < 0) return NULL;

		s2n(TLSEXT_TYPE_status_request, ret);
		s2n(1 + 2 + 2, ret);
		/* status_type */
		*(ret++) = TLSEXT_STATUSTYPE_ocsp;
		/* responder_id_list - empty */
		s2n(0, ret);
		/* request_extensions - empty */
		s2n(0, ret);
		}

	if (s->ctx->next_proto_select_cb && !s->s3->tmp.finish_md_len)
		{
		/* The client advertises an emtpy extension to indicate its
		 * support for Next Protocol Negotiation */
		if (limit - ret - 4 < 0)
			return NULL;
		s2n(TLSEXT_TYPE_next_proto_neg,ret);
		s2n(0,ret);
		}

	if (s->signed_cert_timestamps_enabled && !s->s3->tmp.finish_md_len)
		{
		/* The client advertises an empty extension to indicate its support for
		 * certificate timestamps. */
		if (limit - ret - 4 < 0)
			return NULL;
		s2n(TLSEXT_TYPE_certificate_timestamp,ret);
		s2n(0,ret);
		}

	if (s->alpn_client_proto_list && !s->s3->tmp.finish_md_len)
		{
		if ((size_t)(limit - ret) < 6 + s->alpn_client_proto_list_len)
			return NULL;
		s2n(TLSEXT_TYPE_application_layer_protocol_negotiation,ret);
		s2n(2 + s->alpn_client_proto_list_len,ret);
		s2n(s->alpn_client_proto_list_len,ret);
		memcpy(ret, s->alpn_client_proto_list,
		       s->alpn_client_proto_list_len);
		ret += s->alpn_client_proto_list_len;
		}

	if (s->tlsext_channel_id_enabled)
		{
		/* The client advertises an emtpy extension to indicate its
		 * support for Channel ID. */
		if (limit - ret - 4 < 0)
			return NULL;
		if (s->ctx->tlsext_channel_id_enabled_new)
			s2n(TLSEXT_TYPE_channel_id_new,ret);
		else
			s2n(TLSEXT_TYPE_channel_id,ret);
		s2n(0,ret);
		}

        if(SSL_get_srtp_profiles(s))
                {
                int el;

                ssl_add_clienthello_use_srtp_ext(s, 0, &el, 0);
                
                if((limit - ret - 4 - el) < 0) return NULL;

                s2n(TLSEXT_TYPE_use_srtp,ret);
                s2n(el,ret);

                if(ssl_add_clienthello_use_srtp_ext(s, ret, &el, el))
			{
			OPENSSL_PUT_ERROR(SSL, ssl_add_clienthello_tlsext, ERR_R_INTERNAL_ERROR);
			return NULL;
			}
                ret += el;
                }

	if (using_ecc)
		{
		/* Add TLS extension ECPointFormats to the ClientHello message */
		long lenmax; 
		const uint8_t *formats;
		const uint16_t *curves;
		size_t formats_len, curves_len, i;

		tls1_get_formatlist(s, &formats, &formats_len);

		if ((lenmax = limit - ret - 5) < 0) return NULL; 
		if (formats_len > (size_t)lenmax) return NULL;
		if (formats_len > 255)
			{
			OPENSSL_PUT_ERROR(SSL, ssl_add_clienthello_tlsext, ERR_R_INTERNAL_ERROR);
			return NULL;
			}
		
		s2n(TLSEXT_TYPE_ec_point_formats,ret);
		s2n(formats_len + 1,ret);
		*(ret++) = (unsigned char)formats_len;
		memcpy(ret, formats, formats_len);
		ret+=formats_len;

		/* Add TLS extension EllipticCurves to the ClientHello message */
		tls1_get_curvelist(s, 0, &curves, &curves_len);

		if ((lenmax = limit - ret - 6) < 0) return NULL; 
		if ((curves_len * 2) > (size_t)lenmax) return NULL;
		if ((curves_len * 2) > 65532)
			{
			OPENSSL_PUT_ERROR(SSL, ssl_add_clienthello_tlsext, ERR_R_INTERNAL_ERROR);
			return NULL;
			}
		
		s2n(TLSEXT_TYPE_elliptic_curves,ret);
		s2n((curves_len * 2) + 2, ret);

		/* NB: draft-ietf-tls-ecc-12.txt uses a one-byte prefix for
		 * elliptic_curve_list, but the examples use two bytes.
		 * http://www1.ietf.org/mail-archive/web/tls/current/msg00538.html
		 * resolves this to two bytes.
		 */
		s2n(curves_len * 2, ret);
		for (i = 0; i < curves_len; i++)
			{
			s2n(curves[i], ret);
			}
		}

#ifdef TLSEXT_TYPE_padding
	/* Add padding to workaround bugs in F5 terminators.
	 * See https://tools.ietf.org/html/draft-agl-tls-padding-03
	 *
	 * NB: because this code works out the length of all existing
	 * extensions it MUST always appear last. */
	if (header_len > 0)
		{
		header_len += ret - orig;
		if (header_len > 0xff && header_len < 0x200)
			{
			size_t padding_len = 0x200 - header_len;
			/* Extensions take at least four bytes to encode. Always
			 * include least one byte of data if including the
			 * extension. WebSphere Application Server 7.0 is
			 * intolerant to the last extension being zero-length. */
			if (padding_len >= 4 + 1)
				padding_len -= 4;
			else
				padding_len = 1;
			if (limit - ret - 4 - (long)padding_len < 0)
				return NULL;

			s2n(TLSEXT_TYPE_padding, ret);
			s2n(padding_len, ret);
			memset(ret, 0, padding_len);
			ret += padding_len;
			}
		}
#endif

	if ((extdatalen = ret-orig-2)== 0)
		return orig;

	s2n(extdatalen, orig);
	return ret;
	}

unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, unsigned char *limit)
	{
	int extdatalen=0;
	unsigned char *orig = buf;
	unsigned char *ret = buf;
	int next_proto_neg_seen;
	unsigned long alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
	unsigned long alg_a = s->s3->tmp.new_cipher->algorithm_auth;
	int using_ecc = (alg_k & SSL_kEECDH) || (alg_a & SSL_aECDSA);
	using_ecc = using_ecc && (s->session->tlsext_ecpointformatlist != NULL);
	/* don't add extensions for SSLv3, unless doing secure renegotiation */
	if (s->version == SSL3_VERSION && !s->s3->send_connection_binding)
		return orig;
	
	ret+=2;
	if (ret>=limit) return NULL; /* this really never occurs, but ... */

	if (!s->hit && s->should_ack_sni && s->session->tlsext_hostname != NULL)
		{ 
		if ((long)(limit - ret - 4) < 0) return NULL; 

		s2n(TLSEXT_TYPE_server_name,ret);
		s2n(0,ret);
		}

	if(s->s3->send_connection_binding)
        {
          int el;
          
          if(!ssl_add_serverhello_renegotiate_ext(s, 0, &el, 0))
              {
              OPENSSL_PUT_ERROR(SSL, ssl_add_serverhello_tlsext, ERR_R_INTERNAL_ERROR);
              return NULL;
              }

          if((limit - ret - 4 - el) < 0) return NULL;
          
          s2n(TLSEXT_TYPE_renegotiate,ret);
          s2n(el,ret);

          if(!ssl_add_serverhello_renegotiate_ext(s, ret, &el, el))
              {
              OPENSSL_PUT_ERROR(SSL, ssl_add_serverhello_tlsext, ERR_R_INTERNAL_ERROR);
              return NULL;
              }

          ret += el;
        }

	if (using_ecc)
		{
		const unsigned char *plist;
		size_t plistlen;
		/* Add TLS extension ECPointFormats to the ServerHello message */
		long lenmax; 

		tls1_get_formatlist(s, &plist, &plistlen);

		if ((lenmax = limit - ret - 5) < 0) return NULL; 
		if (plistlen > (size_t)lenmax) return NULL;
		if (plistlen > 255)
			{
			OPENSSL_PUT_ERROR(SSL, ssl_add_serverhello_tlsext, ERR_R_INTERNAL_ERROR);
			return NULL;
			}
		
		s2n(TLSEXT_TYPE_ec_point_formats,ret);
		s2n(plistlen + 1,ret);
		*(ret++) = (unsigned char) plistlen;
		memcpy(ret, plist, plistlen);
		ret+=plistlen;

		}
	/* Currently the server should not respond with a SupportedCurves extension */

	if (s->tlsext_ticket_expected
		&& !(SSL_get_options(s) & SSL_OP_NO_TICKET)) 
		{ 
		if ((long)(limit - ret - 4) < 0) return NULL; 
		s2n(TLSEXT_TYPE_session_ticket,ret);
		s2n(0,ret);
		}

	if (s->s3->tmp.certificate_status_expected)
		{ 
		if ((long)(limit - ret - 4) < 0) return NULL; 
		s2n(TLSEXT_TYPE_status_request,ret);
		s2n(0,ret);
		}

        if(s->srtp_profile)
                {
                int el;

                ssl_add_serverhello_use_srtp_ext(s, 0, &el, 0);
                
                if((limit - ret - 4 - el) < 0) return NULL;

                s2n(TLSEXT_TYPE_use_srtp,ret);
                s2n(el,ret);

                if(ssl_add_serverhello_use_srtp_ext(s, ret, &el, el))
			{
			OPENSSL_PUT_ERROR(SSL, ssl_add_serverhello_tlsext, ERR_R_INTERNAL_ERROR);
			return NULL;
			}
                ret+=el;
                }

	next_proto_neg_seen = s->s3->next_proto_neg_seen;
	s->s3->next_proto_neg_seen = 0;
	if (next_proto_neg_seen && s->ctx->next_protos_advertised_cb)
		{
		const unsigned char *npa;
		unsigned int npalen;
		int r;

		r = s->ctx->next_protos_advertised_cb(s, &npa, &npalen, s->ctx->next_protos_advertised_cb_arg);
		if (r == SSL_TLSEXT_ERR_OK)
			{
			if ((long)(limit - ret - 4 - npalen) < 0) return NULL;
			s2n(TLSEXT_TYPE_next_proto_neg,ret);
			s2n(npalen,ret);
			memcpy(ret, npa, npalen);
			ret += npalen;
			s->s3->next_proto_neg_seen = 1;
			}
		}

	if (s->s3->alpn_selected)
		{
		const uint8_t *selected = s->s3->alpn_selected;
		size_t len = s->s3->alpn_selected_len;

		if ((long)(limit - ret - 4 - 2 - 1 - len) < 0)
			return NULL;
		s2n(TLSEXT_TYPE_application_layer_protocol_negotiation,ret);
		s2n(3 + len,ret);
		s2n(1 + len,ret);
		*ret++ = len;
		memcpy(ret, selected, len);
		ret += len;
		}

	/* If the client advertised support for Channel ID, and we have it
	 * enabled, then we want to echo it back. */
	if (s->s3->tlsext_channel_id_valid)
		{
		if (limit - ret - 4 < 0)
			return NULL;
		if (s->s3->tlsext_channel_id_new)
			s2n(TLSEXT_TYPE_channel_id_new,ret);
		else
			s2n(TLSEXT_TYPE_channel_id,ret);
		s2n(0,ret);
		}

	if ((extdatalen = ret-orig-2) == 0)
		return orig;

	s2n(extdatalen, orig);
	return ret;
	}

/* tls1_alpn_handle_client_hello is called to process the ALPN extension in a
 * ClientHello.
 *   cbs: the contents of the extension, not including the type and length.
 *   out_alert: a pointer to the alert value to send in the event of a zero
 *       return.
 *
 *   returns: 1 on success. */
static int tls1_alpn_handle_client_hello(SSL *s, CBS *cbs, int *out_alert)
	{
	CBS protocol_name_list, protocol_name_list_copy;
	const unsigned char *selected;
	unsigned char selected_len;
	int r;

	if (s->ctx->alpn_select_cb == NULL)
		return 1;

	if (!CBS_get_u16_length_prefixed(cbs, &protocol_name_list) ||
		CBS_len(cbs) != 0 ||
		CBS_len(&protocol_name_list) < 2)
		goto parse_error;

	/* Validate the protocol list. */
	protocol_name_list_copy = protocol_name_list;
	while (CBS_len(&protocol_name_list_copy) > 0)
		{
		CBS protocol_name;

		if (!CBS_get_u8_length_prefixed(&protocol_name_list_copy, &protocol_name))
			goto parse_error;
		}

	r = s->ctx->alpn_select_cb(s, &selected, &selected_len,
		CBS_data(&protocol_name_list), CBS_len(&protocol_name_list),
		s->ctx->alpn_select_cb_arg);
	if (r == SSL_TLSEXT_ERR_OK) {
		if (s->s3->alpn_selected)
			OPENSSL_free(s->s3->alpn_selected);
		s->s3->alpn_selected = BUF_memdup(selected, selected_len);
		if (!s->s3->alpn_selected)
			{
			*out_alert = SSL_AD_INTERNAL_ERROR;
			return 0;
			}
		s->s3->alpn_selected_len = selected_len;
	}
	return 1;

parse_error:
	*out_alert = SSL_AD_DECODE_ERROR;
	return 0;
	}

static int ssl_scan_clienthello_tlsext(SSL *s, CBS *cbs, int *out_alert)
	{	
	int renegotiate_seen = 0;
	CBS extensions;
	size_t i;

	s->should_ack_sni = 0;
	s->s3->next_proto_neg_seen = 0;
	s->s3->tmp.certificate_status_expected = 0;

	if (s->s3->alpn_selected)
		{
		OPENSSL_free(s->s3->alpn_selected);
		s->s3->alpn_selected = NULL;
		}

	/* Clear any signature algorithms extension received */
	if (s->cert->peer_sigalgs)
		{
		OPENSSL_free(s->cert->peer_sigalgs);
		s->cert->peer_sigalgs = NULL;
		}
	/* Clear any shared sigtnature algorithms */
	if (s->cert->shared_sigalgs)
		{
		OPENSSL_free(s->cert->shared_sigalgs);
		s->cert->shared_sigalgs = NULL;
		}
	/* 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;
		}

	/* There may be no extensions. */
	if (CBS_len(cbs) == 0)
		{
		goto ri_check;
		}

	/* Decode the extensions block and check it is valid. */
	if (!CBS_get_u16_length_prefixed(cbs, &extensions) ||
		!tls1_check_duplicate_extensions(&extensions))
		{
		*out_alert = SSL_AD_DECODE_ERROR;
		return 0;
		}

	while (CBS_len(&extensions) != 0)
		{
		uint16_t type;
		CBS extension;

		/* Decode the next extension. */
		if (!CBS_get_u16(&extensions, &type) ||
			!CBS_get_u16_length_prefixed(&extensions, &extension))
			{
			*out_alert = SSL_AD_DECODE_ERROR;
			return 0;
			}

		if (s->tlsext_debug_cb)
			{
			s->tlsext_debug_cb(s, 0, type, (unsigned char*)CBS_data(&extension),
				CBS_len(&extension), s->tlsext_debug_arg);
			}

/* The servername extension is treated as follows:

   - Only the hostname type is supported with a maximum length of 255.
   - The servername is rejected if too long or if it contains zeros,
     in which case an fatal alert is generated.
   - The servername field is maintained together with the session cache.
   - When a session is resumed, the servername call back invoked in order
     to allow the application to position itself to the right context. 
   - The servername is acknowledged if it is new for a session or when 
     it is identical to a previously used for the same session. 
     Applications can control the behaviour.  They can at any time
     set a 'desirable' servername for a new SSL object. This can be the
     case for example with HTTPS when a Host: header field is received and
     a renegotiation is requested. In this case, a possible servername
     presented in the new client hello is only acknowledged if it matches
     the value of the Host: field. 
   - Applications must  use SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
     if they provide for changing an explicit servername context for the session,
     i.e. when the session has been established with a servername extension. 
   - On session reconnect, the servername extension may be absent. 

*/      

		if (type == TLSEXT_TYPE_server_name)
			{
			CBS server_name_list;
			char have_seen_host_name = 0;

			if (!CBS_get_u16_length_prefixed(&extension, &server_name_list) ||
				CBS_len(&server_name_list) < 1 ||
				CBS_len(&extension) != 0)
				{
				*out_alert = SSL_AD_DECODE_ERROR;
				return 0;
				}

			/* Decode each ServerName in the extension. */
			while (CBS_len(&server_name_list) > 0)
				{
				uint8_t name_type;
				CBS host_name;

				/* Decode the NameType. */
				if (!CBS_get_u8(&server_name_list, &name_type))
					{
					*out_alert = SSL_AD_DECODE_ERROR;
					return 0;
					}

				/* Only host_name is supported. */
				if (name_type != TLSEXT_NAMETYPE_host_name)
					continue;

				if (have_seen_host_name)
					{
					/* The ServerNameList MUST NOT contain
					 * more than one name of the same
					 * name_type. */
					*out_alert = SSL_AD_DECODE_ERROR;
					return 0;
					}

				have_seen_host_name = 1;

				if (!CBS_get_u16_length_prefixed(&server_name_list, &host_name) ||
					CBS_len(&host_name) < 1)
					{
					*out_alert = SSL_AD_DECODE_ERROR;
					return 0;
					}

				if (CBS_len(&host_name) > TLSEXT_MAXLEN_host_name ||
					CBS_contains_zero_byte(&host_name))
					{
					*out_alert = SSL_AD_UNRECOGNIZED_NAME;
					return 0;
					}

				if (!s->hit)
					{
					assert(s->session->tlsext_hostname == NULL);
					if (s->session->tlsext_hostname)
						{
						/* This should be impossible. */
						*out_alert = SSL_AD_DECODE_ERROR;
						return 0;
						}

					/* Copy the hostname as a string. */
					if (!CBS_strdup(&host_name, &s->session->tlsext_hostname))
						{
						*out_alert = SSL_AD_INTERNAL_ERROR;
						return 0;
						}

					s->should_ack_sni = 1;
					}
				}
			}

		else if (type == TLSEXT_TYPE_ec_point_formats)
			{
			CBS ec_point_format_list;

			if (!CBS_get_u8_length_prefixed(&extension, &ec_point_format_list) ||
				CBS_len(&extension) != 0)
				{
				*out_alert = SSL_AD_DECODE_ERROR;
				return 0;
				}

			if (!s->hit)
				{
				if (!CBS_stow(&ec_point_format_list,
						&s->session->tlsext_ecpointformatlist,
						&s->session->tlsext_ecpointformatlist_length))
					{
					*out_alert = SSL_AD_INTERNAL_ERROR;
					return 0;
					}
				}
			}
		else if (type == TLSEXT_TYPE_elliptic_curves)
			{
			CBS elliptic_curve_list;
			size_t i, num_curves;

			if (!CBS_get_u16_length_prefixed(&extension, &elliptic_curve_list) ||
				CBS_len(&elliptic_curve_list) == 0 ||
				(CBS_len(&elliptic_curve_list) & 1) != 0 ||
				CBS_len(&extension) != 0)
				{
				*out_alert = SSL_AD_DECODE_ERROR;
				return 0;
				}

			if (!s->hit)
				{
				if (s->session->tlsext_ellipticcurvelist)
					{
					OPENSSL_free(s->session->tlsext_ellipticcurvelist);
					s->session->tlsext_ellipticcurvelist_length = 0;
					}
				s->session->tlsext_ellipticcurvelist =
					(uint16_t*)OPENSSL_malloc(CBS_len(&elliptic_curve_list));
				if (s->session->tlsext_ellipticcurvelist == NULL)
					{
					*out_alert = SSL_AD_INTERNAL_ERROR;
					return 0;
					}
				num_curves = CBS_len(&elliptic_curve_list) / 2;
				for (i = 0; i < num_curves; i++)
					{
					if (!CBS_get_u16(&elliptic_curve_list,
							&s->session->tlsext_ellipticcurvelist[i]))
						{
						*out_alert = SSL_AD_INTERNAL_ERROR;
						return 0;
						}
					}
				if (CBS_len(&elliptic_curve_list) != 0)
					{
					*out_alert = SSL_AD_INTERNAL_ERROR;
					return 0;
					}
				s->session->tlsext_ellipticcurvelist_length = num_curves;
				}
			}
		else if (type == TLSEXT_TYPE_session_ticket)
			{
			if (s->tls_session_ticket_ext_cb &&
				!s->tls_session_ticket_ext_cb(s, CBS_data(&extension), CBS_len(&extension), s->tls_session_ticket_ext_cb_arg))
				{
				*out_alert = SSL_AD_INTERNAL_ERROR;
				return 0;
				}
			}
		else if (type == TLSEXT_TYPE_renegotiate)
			{
			if (!ssl_parse_clienthello_renegotiate_ext(s, &extension, out_alert))
				return 0;
			renegotiate_seen = 1;
			}
		else if (type == TLSEXT_TYPE_signature_algorithms)
			{
			CBS supported_signature_algorithms;

			if (!CBS_get_u16_length_prefixed(&extension, &supported_signature_algorithms) ||
				CBS_len(&extension) != 0)
				{
				*out_alert = SSL_AD_DECODE_ERROR;
				return 0;
				}

			/* Ensure the signature algorithms are non-empty. It
			 * contains a list of SignatureAndHashAlgorithms
			 * which are two bytes each. */
			if (CBS_len(&supported_signature_algorithms) == 0 ||
				(CBS_len(&supported_signature_algorithms) % 2) != 0)
				{
				*out_alert = SSL_AD_DECODE_ERROR;
				return 0;
				}

			if (!tls1_process_sigalgs(s, &supported_signature_algorithms))
				{
				*out_alert = SSL_AD_DECODE_ERROR;
				return 0;
				}
			/* If sigalgs received and no shared algorithms fatal
			 * error.
			 */
			if (s->cert->peer_sigalgs && !s->cert->shared_sigalgs)
				{
				OPENSSL_PUT_ERROR(SSL, ssl_add_serverhello_tlsext, SSL_R_NO_SHARED_SIGATURE_ALGORITHMS);
				*out_alert = SSL_AD_ILLEGAL_PARAMETER;
				return 0;
				}
			}

		else if (type == TLSEXT_TYPE_next_proto_neg &&
			 s->s3->tmp.finish_md_len == 0 &&
			 s->s3->alpn_selected == NULL)
			{
			/* The extension must be empty. */
			if (CBS_len(&extension) != 0)
				{
				*out_alert = SSL_AD_DECODE_ERROR;
				return 0;
				}

			/* We shouldn't accept this extension on a
			 * renegotiation.
			 *
			 * s->new_session will be set on renegotiation, but we
			 * probably shouldn't rely that it couldn't be set on
			 * the initial renegotation too in certain cases (when
			 * there's some other reason to disallow resuming an
			 * earlier session -- the current code won't be doing
			 * anything like that, but this might change).

			 * A valid sign that there's been a previous handshake
			 * in this connection is if s->s3->tmp.finish_md_len >
			 * 0.  (We are talking about a check that will happen
			 * in the Hello protocol round, well before a new
			 * Finished message could have been computed.) */
			s->s3->next_proto_neg_seen = 1;
			}

		else if (type == TLSEXT_TYPE_application_layer_protocol_negotiation &&
			 s->ctx->alpn_select_cb &&
			 s->s3->tmp.finish_md_len == 0)
			{
			if (!tls1_alpn_handle_client_hello(s, &extension, out_alert))
				return 0;
			/* ALPN takes precedence over NPN. */
			s->s3->next_proto_neg_seen = 0;
			}

		else if (type == TLSEXT_TYPE_channel_id &&
			 s->tlsext_channel_id_enabled)
			{
			/* The extension must be empty. */
			if (CBS_len(&extension) != 0)
				{
				*out_alert = SSL_AD_DECODE_ERROR;
				return 0;
				}

			s->s3->tlsext_channel_id_valid = 1;
			}

		else if (type == TLSEXT_TYPE_channel_id_new &&
			 s->tlsext_channel_id_enabled)
			{
			/* The extension must be empty. */
			if (CBS_len(&extension) != 0)
				{
				*out_alert = SSL_AD_DECODE_ERROR;
				return 0;
				}

			s->s3->tlsext_channel_id_valid = 1;
			s->s3->tlsext_channel_id_new = 1;
			}


		/* session ticket processed earlier */
		else if (type == TLSEXT_TYPE_use_srtp)
                        {
			if (!ssl_parse_clienthello_use_srtp_ext(s, &extension, out_alert))
				return 0;
                        }
		}

	ri_check:

	/* Need RI if renegotiating */

	if (!renegotiate_seen && s->renegotiate &&
		!(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION))
		{
		*out_alert = SSL_AD_HANDSHAKE_FAILURE;
	 	OPENSSL_PUT_ERROR(SSL, ssl_add_serverhello_tlsext, SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
		return 0;
		}
	/* If no signature algorithms extension set default values */
	if (!s->cert->peer_sigalgs)
		ssl_cert_set_default_md(s->cert);

	return 1;
	}

int ssl_parse_clienthello_tlsext(SSL *s, CBS *cbs)
	{
	int alert = -1;
	if (ssl_scan_clienthello_tlsext(s, cbs, &alert) <= 0)
		{
		ssl3_send_alert(s, SSL3_AL_FATAL, alert);
		return 0;
		}

	if (ssl_check_clienthello_tlsext(s) <= 0)
		{
		OPENSSL_PUT_ERROR(SSL, ssl_parse_clienthello_tlsext, SSL_R_CLIENTHELLO_TLSEXT);
		return 0;
		}
	return 1;
	}

/* ssl_next_proto_validate validates a Next Protocol Negotiation block. No
 * elements of zero length are allowed and the set of elements must exactly fill
 * the length of the block. */
static char ssl_next_proto_validate(const CBS *cbs)
	{
	CBS copy = *cbs;

	while (CBS_len(&copy) != 0)
		{
		CBS proto;
		if (!CBS_get_u8_length_prefixed(&copy, &proto) ||
			CBS_len(&proto) == 0)
			{
			return 0;
			}
		}
	return 1;
	}

static int ssl_scan_serverhello_tlsext(SSL *s, CBS *cbs, int *out_alert)
	{
	int tlsext_servername = 0;
	int renegotiate_seen = 0;
	CBS extensions;

	/* TODO(davidben): Move all of these to some per-handshake state that
	 * gets systematically reset on a new handshake; perhaps allocate it
	 * fresh each time so it's not even kept around post-handshake. */
	s->s3->next_proto_neg_seen = 0;

	s->tlsext_ticket_expected = 0;
	s->s3->tmp.certificate_status_expected = 0;

	if (s->s3->alpn_selected)
		{
		OPENSSL_free(s->s3->alpn_selected);
		s->s3->alpn_selected = NULL;
		}

	/* There may be no extensions. */
	if (CBS_len(cbs) == 0)
		{
		goto ri_check;
		}

	/* Decode the extensions block and check it is valid. */
	if (!CBS_get_u16_length_prefixed(cbs, &extensions) ||
		!tls1_check_duplicate_extensions(&extensions))
		{
		*out_alert = SSL_AD_DECODE_ERROR;
		return 0;
		}

	while (CBS_len(&extensions) != 0)
		{
		uint16_t type;
		CBS extension;

		/* Decode the next extension. */
		if (!CBS_get_u16(&extensions, &type) ||
			!CBS_get_u16_length_prefixed(&extensions, &extension))
			{
			*out_alert = SSL_AD_DECODE_ERROR;
			return 0;
			}

		if (s->tlsext_debug_cb)
			{
			s->tlsext_debug_cb(s, 1, type, (unsigned char*)CBS_data(&extension),
				CBS_len(&extension), s->tlsext_debug_arg);
			}

		if (type == TLSEXT_TYPE_server_name)
			{
			/* The extension must be empty. */
			if (CBS_len(&extension) != 0)
				{
				*out_alert = SSL_AD_DECODE_ERROR;
				return 0;
				}
			/* We must have sent it in ClientHello. */
			if (s->tlsext_hostname == NULL)
				{
				*out_alert = SSL_AD_UNSUPPORTED_EXTENSION;
				return 0;
				}
			tlsext_servername = 1;
			}
		else if (type == TLSEXT_TYPE_ec_point_formats)
			{
			CBS ec_point_format_list;

			if (!CBS_get_u8_length_prefixed(&extension, &ec_point_format_list) ||
				CBS_len(&extension) != 0)
				{
				*out_alert = SSL_AD_DECODE_ERROR;
				return 0;
				}

			if (!s->hit)
				{
				if (!CBS_stow(&ec_point_format_list,
						&s->session->tlsext_ecpointformatlist,
						&s->session->tlsext_ecpointformatlist_length))
					{
					*out_alert = SSL_AD_INTERNAL_ERROR;
					return 0;
					}
				}
			}
		else if (type == TLSEXT_TYPE_session_ticket)
			{
			if (s->tls_session_ticket_ext_cb &&
				!s->tls_session_ticket_ext_cb(s, CBS_data(&extension), CBS_len(&extension),
                                        s->tls_session_ticket_ext_cb_arg))
				{
				*out_alert = SSL_AD_INTERNAL_ERROR;
				return 0;
				}

			if ((SSL_get_options(s) & SSL_OP_NO_TICKET) || CBS_len(&extension) > 0)
				{
				*out_alert = SSL_AD_UNSUPPORTED_EXTENSION;
				return 0;
				}

			s->tlsext_ticket_expected = 1;
			}
		else if (type == TLSEXT_TYPE_status_request)
			{
			/* The extension MUST be empty and may only sent if
			 * we've requested a status request message. */
			if (CBS_len(&extension) != 0)
				{
				*out_alert = SSL_AD_DECODE_ERROR;
				return 0;
				}
			if (!s->ocsp_stapling_enabled)
				{
				*out_alert = SSL_AD_UNSUPPORTED_EXTENSION;
				return 0;
				}
			/* Set a flag to expect a CertificateStatus message */
			s->s3->tmp.certificate_status_expected = 1;
			}
		else if (type == TLSEXT_TYPE_next_proto_neg && s->s3->tmp.finish_md_len == 0) {
		unsigned char *selected;
		unsigned char selected_len;

		/* We must have requested it. */
		if (s->ctx->next_proto_select_cb == NULL)
			{
			*out_alert = SSL_AD_UNSUPPORTED_EXTENSION;
			return 0;
			}

		/* The data must be valid. */
		if (!ssl_next_proto_validate(&extension))
			{
			*out_alert = SSL_AD_DECODE_ERROR;
			return 0;
			}

		if (s->ctx->next_proto_select_cb(s, &selected, &selected_len,
				CBS_data(&extension), CBS_len(&extension),
				s->ctx->next_proto_select_cb_arg) != SSL_TLSEXT_ERR_OK)
			{
			*out_alert = SSL_AD_INTERNAL_ERROR;
			return 0;
			}

		s->next_proto_negotiated = BUF_memdup(selected, selected_len);
		if (s->next_proto_negotiated == NULL)
			{
			*out_alert = SSL_AD_INTERNAL_ERROR;
			return 0;
			}
		s->next_proto_negotiated_len = selected_len;
		s->s3->next_proto_neg_seen = 1;
		}
		else if (type == TLSEXT_TYPE_application_layer_protocol_negotiation)
			{
			CBS protocol_name_list, protocol_name;

			/* We must have requested it. */
			if (s->alpn_client_proto_list == NULL)
				{
				*out_alert = SSL_AD_UNSUPPORTED_EXTENSION;
				return 0;
				}

			/* The extension data consists of a ProtocolNameList
			 * which must have exactly one ProtocolName. Each of
			 * these is length-prefixed. */
			if (!CBS_get_u16_length_prefixed(&extension, &protocol_name_list) ||
				CBS_len(&extension) != 0 ||
				!CBS_get_u8_length_prefixed(&protocol_name_list, &protocol_name) ||
				CBS_len(&protocol_name_list) != 0)
				{
				*out_alert = SSL_AD_DECODE_ERROR;
				return 0;
				}

			if (!CBS_stow(&protocol_name,
					&s->s3->alpn_selected,
					&s->s3->alpn_selected_len))
				{
				*out_alert = SSL_AD_INTERNAL_ERROR;
				return 0;
				}
			}

		else if (type == TLSEXT_TYPE_channel_id)
			{
			if (CBS_len(&extension) != 0)
				{
				*out_alert = SSL_AD_DECODE_ERROR;
				return 0;
				}
			s->s3->tlsext_channel_id_valid = 1;
			}
		else if (type == TLSEXT_TYPE_channel_id_new)
			{
			if (CBS_len(&extension) != 0)
				{
				*out_alert = SSL_AD_DECODE_ERROR;
				return 0;
				}
			s->s3->tlsext_channel_id_valid = 1;
			s->s3->tlsext_channel_id_new = 1;
			}
		else if (type == TLSEXT_TYPE_certificate_timestamp)
			{
			if (CBS_len(&extension) == 0)
				{
				*out_alert = SSL_AD_DECODE_ERROR;
				return 0;
				}

			/* Session resumption uses the original session information. */
			if (!s->hit)
				{
				if (!CBS_stow(&extension,
					&s->session->tlsext_signed_cert_timestamp_list,
					&s->session->tlsext_signed_cert_timestamp_list_length))
					{
					*out_alert = SSL_AD_INTERNAL_ERROR;
					return 0;
					}
				}
			}
		else if (type == TLSEXT_TYPE_renegotiate)
			{
			if (!ssl_parse_serverhello_renegotiate_ext(s, &extension, out_alert))
				return 0;
			renegotiate_seen = 1;
			}
		else if (type == TLSEXT_TYPE_use_srtp)
                        {
                        if (!ssl_parse_serverhello_use_srtp_ext(s, &extension, out_alert))
                                return 0;
                        }
		}

	if (!s->hit && tlsext_servername == 1)
		{
 		if (s->tlsext_hostname)
			{
			if (s->session->tlsext_hostname == NULL)
				{
				s->session->tlsext_hostname = BUF_strdup(s->tlsext_hostname);	
				if (!s->session->tlsext_hostname)
					{
					*out_alert = SSL_AD_UNRECOGNIZED_NAME;
					return 0;
					}
				}
			else 
				{
				*out_alert = SSL_AD_DECODE_ERROR;
				return 0;
				}
			}
		}

	ri_check:

	/* Determine if we need to see RI. Strictly speaking if we want to
	 * avoid an attack we should *always* see RI even on initial server
	 * hello because the client doesn't see any renegotiation during an
	 * attack. However this would mean we could not connect to any server
	 * which doesn't support RI so for the immediate future tolerate RI
	 * absence on initial connect only.
	 */
	if (!renegotiate_seen
		&& !(s->options & SSL_OP_LEGACY_SERVER_CONNECT)
		&& !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION))
		{
		*out_alert = SSL_AD_HANDSHAKE_FAILURE;
		OPENSSL_PUT_ERROR(SSL, ssl_scan_serverhello_tlsext, SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
		return 0;
		}

	return 1;
	}


int ssl_prepare_clienthello_tlsext(SSL *s)
	{
	return 1;
	}

int ssl_prepare_serverhello_tlsext(SSL *s)
	{
	return 1;
	}

static int ssl_check_clienthello_tlsext(SSL *s)
	{
	int ret=SSL_TLSEXT_ERR_NOACK;
	int al = SSL_AD_UNRECOGNIZED_NAME;

	/* The handling of the ECPointFormats extension is done elsewhere, namely in 
	 * ssl3_choose_cipher in s3_lib.c.
	 */
	/* The handling of the EllipticCurves extension is done elsewhere, namely in 
	 * ssl3_choose_cipher in s3_lib.c.
	 */

	if (s->ctx != NULL && s->ctx->tlsext_servername_callback != 0) 
		ret = s->ctx->tlsext_servername_callback(s, &al, s->ctx->tlsext_servername_arg);
	else if (s->initial_ctx != NULL && s->initial_ctx->tlsext_servername_callback != 0) 		
		ret = s->initial_ctx->tlsext_servername_callback(s, &al, s->initial_ctx->tlsext_servername_arg);

	switch (ret)
		{
		case SSL_TLSEXT_ERR_ALERT_FATAL:
			ssl3_send_alert(s,SSL3_AL_FATAL,al); 
			return -1;

		case SSL_TLSEXT_ERR_ALERT_WARNING:
			ssl3_send_alert(s,SSL3_AL_WARNING,al);
			return 1;

		case SSL_TLSEXT_ERR_NOACK:
			s->should_ack_sni = 0;
			return 1;

		default:
			return 1;
		}
	}

static int ssl_check_serverhello_tlsext(SSL *s)
	{
	int ret=SSL_TLSEXT_ERR_NOACK;
	int al = SSL_AD_UNRECOGNIZED_NAME;

	/* If we are client and using an elliptic curve cryptography cipher
	 * suite, then if server returns an EC point formats lists extension
	 * it must contain uncompressed.
	 */
	unsigned long alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
	unsigned long alg_a = s->s3->tmp.new_cipher->algorithm_auth;
	if ((s->tlsext_ecpointformatlist != NULL) && (s->tlsext_ecpointformatlist_length > 0) && 
	    (s->session->tlsext_ecpointformatlist != NULL) && (s->session->tlsext_ecpointformatlist_length > 0) && 
	    ((alg_k & SSL_kEECDH) || (alg_a & SSL_aECDSA)))
		{
		/* we are using an ECC cipher */
		size_t i;
		unsigned char *list;
		int found_uncompressed = 0;
		list = s->session->tlsext_ecpointformatlist;
		for (i = 0; i < s->session->tlsext_ecpointformatlist_length; i++)
			{
			if (*(list++) == TLSEXT_ECPOINTFORMAT_uncompressed)
				{
				found_uncompressed = 1;
				break;
				}
			}
		if (!found_uncompressed)
			{
			OPENSSL_PUT_ERROR(SSL, ssl_add_serverhello_tlsext, SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST);
			return -1;
			}
		}
	ret = SSL_TLSEXT_ERR_OK;

	if (s->ctx != NULL && s->ctx->tlsext_servername_callback != 0) 
		ret = s->ctx->tlsext_servername_callback(s, &al, s->ctx->tlsext_servername_arg);
	else if (s->initial_ctx != NULL && s->initial_ctx->tlsext_servername_callback != 0) 		
		ret = s->initial_ctx->tlsext_servername_callback(s, &al, s->initial_ctx->tlsext_servername_arg);

	switch (ret)
		{
		case SSL_TLSEXT_ERR_ALERT_FATAL:
			ssl3_send_alert(s,SSL3_AL_FATAL,al);
			return -1;

		case SSL_TLSEXT_ERR_ALERT_WARNING:
			ssl3_send_alert(s,SSL3_AL_WARNING,al);
			return 1;

		default:
			return 1;
		}
	}

int ssl_parse_serverhello_tlsext(SSL *s, CBS *cbs)
	{
	int alert = -1;
	if (s->version < SSL3_VERSION)
		return 1;

	if (ssl_scan_serverhello_tlsext(s, cbs, &alert) <= 0)
		{
		ssl3_send_alert(s, SSL3_AL_FATAL, alert);
		return 0;
		}

	if (ssl_check_serverhello_tlsext(s) <= 0)
		{
		OPENSSL_PUT_ERROR(SSL, ssl_parse_serverhello_tlsext, SSL_R_SERVERHELLO_TLSEXT);
		return 0;
		}

	return 1;
	}

/* Since the server cache lookup is done early on in the processing of the
 * ClientHello, and other operations depend on the result, we need to handle
 * any TLS session ticket extension at the same time.
 *
 *   ctx: contains the early callback context, which is the result of a
 *       shallow parse of the ClientHello.
 *   ret: (output) on return, if a ticket was decrypted, then this is set to
 *       point to the resulting session.
 *
 * If s->tls_session_secret_cb is set then we are expecting a pre-shared key
 * ciphersuite, in which case we have no use for session tickets and one will
 * never be decrypted, nor will s->tlsext_ticket_expected be set to 1.
 *
 * Returns:
 *   -1: fatal error, either from parsing or decrypting the ticket.
 *    0: no ticket was found (or was ignored, based on settings).
 *    1: a zero length extension was found, indicating that the client supports
 *       session tickets but doesn't currently have one to offer.
 *    2: either s->tls_session_secret_cb was set, or a ticket was offered but
 *       couldn't be decrypted because of a non-fatal error.
 *    3: a ticket was successfully decrypted and *ret was set.
 *
 * Side effects:
 *   Sets s->tlsext_ticket_expected to 1 if the server will have to issue
 *   a new session ticket to the client because the client indicated support
 *   (and s->tls_session_secret_cb is NULL) but the client either doesn't have
 *   a session ticket or we couldn't use the one it gave us, or if
 *   s->ctx->tlsext_ticket_key_cb asked to renew the client's ticket.
 *   Otherwise, s->tlsext_ticket_expected is set to 0.
 */
int tls1_process_ticket(SSL *s, const struct ssl_early_callback_ctx *ctx,
			SSL_SESSION **ret)
	{
	*ret = NULL;
	s->tlsext_ticket_expected = 0;
	const unsigned char *data;
	size_t len;
	int r;

	/* If tickets disabled behave as if no ticket present
	 * to permit stateful resumption.
	 */
	if (SSL_get_options(s) & SSL_OP_NO_TICKET)
		return 0;
	if ((s->version <= SSL3_VERSION) && !ctx->extensions)
		return 0;
	if (!SSL_early_callback_ctx_extension_get(
		ctx, TLSEXT_TYPE_session_ticket, &data, &len))
		{
		return 0;
		}
	if (len == 0)
		{
		/* The client will accept a ticket but doesn't
		 * currently have one. */
		s->tlsext_ticket_expected = 1;
		return 1;
		}
	if (s->tls_session_secret_cb)
		{
		/* Indicate that the ticket couldn't be
		 * decrypted rather than generating the session
		 * from ticket now, trigger abbreviated
		 * handshake based on external mechanism to
		 * calculate the master secret later. */
		return 2;
		}
	r = tls_decrypt_ticket(s, data, len, ctx->session_id,
			       ctx->session_id_len, ret);
	switch (r)
		{
		case 2: /* ticket couldn't be decrypted */
			s->tlsext_ticket_expected = 1;
			return 2;
		case 3: /* ticket was decrypted */
			return r;
		case 4: /* ticket decrypted but need to renew */
			s->tlsext_ticket_expected = 1;
			return 3;
		default: /* fatal error */
			return -1;
		}
	}

/* tls_decrypt_ticket attempts to decrypt a session ticket.
 *
 *   etick: points to the body of the session ticket extension.
 *   eticklen: the length of the session tickets extenion.
 *   sess_id: points at the session ID.
 *   sesslen: the length of the session ID.
 *   psess: (output) on return, if a ticket was decrypted, then this is set to
 *       point to the resulting session.
 *
 * Returns:
 *   -1: fatal error, either from parsing or decrypting the ticket.
 *    2: the ticket couldn't be decrypted.
 *    3: a ticket was successfully decrypted and *psess was set.
 *    4: same as 3, but the ticket needs to be renewed.
 */
static int tls_decrypt_ticket(SSL *s, const unsigned char *etick, int eticklen,
				const unsigned char *sess_id, int sesslen,
				SSL_SESSION **psess)
	{
	SSL_SESSION *sess;
	unsigned char *sdec;
	const unsigned char *p;
	int slen, mlen, renew_ticket = 0;
	unsigned char tick_hmac[EVP_MAX_MD_SIZE];
	HMAC_CTX hctx;
	EVP_CIPHER_CTX ctx;
	SSL_CTX *tctx = s->initial_ctx;
	/* Need at least keyname + iv + some encrypted data */
	if (eticklen < 48)
		return 2;
	/* Initialize session ticket encryption and HMAC contexts */
	HMAC_CTX_init(&hctx);
	EVP_CIPHER_CTX_init(&ctx);
	if (tctx->tlsext_ticket_key_cb)
		{
		unsigned char *nctick = (unsigned char *)etick;
		int rv = tctx->tlsext_ticket_key_cb(s, nctick, nctick + 16,
							&ctx, &hctx, 0);
		if (rv < 0)
			return -1;
		if (rv == 0)
			return 2;
		if (rv == 2)
			renew_ticket = 1;
		}
	else
		{
		/* Check key name matches */
		if (memcmp(etick, tctx->tlsext_tick_key_name, 16))
			return 2;
		HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16,
					tlsext_tick_md(), NULL);
		EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL,
				tctx->tlsext_tick_aes_key, etick + 16);
		}
	/* Attempt to process session ticket, first conduct sanity and
	 * integrity checks on ticket.
	 */
	mlen = HMAC_size(&hctx);
	if (mlen < 0)
		{
		EVP_CIPHER_CTX_cleanup(&ctx);
		return -1;
		}
	eticklen -= mlen;
	/* Check HMAC of encrypted ticket */
	HMAC_Update(&hctx, etick, eticklen);
	HMAC_Final(&hctx, tick_hmac, NULL);
	HMAC_CTX_cleanup(&hctx);
	if (CRYPTO_memcmp(tick_hmac, etick + eticklen, mlen))
		return 2;
	/* Attempt to decrypt session data */
	/* Move p after IV to start of encrypted ticket, update length */
	p = etick + 16 + EVP_CIPHER_CTX_iv_length(&ctx);
	eticklen -= 16 + EVP_CIPHER_CTX_iv_length(&ctx);
	sdec = OPENSSL_malloc(eticklen);
	if (!sdec)
		{
		EVP_CIPHER_CTX_cleanup(&ctx);
		return -1;
		}
	EVP_DecryptUpdate(&ctx, sdec, &slen, p, eticklen);
	if (EVP_DecryptFinal_ex(&ctx, sdec + slen, &mlen) <= 0)
		{
		EVP_CIPHER_CTX_cleanup(&ctx);
		OPENSSL_free(sdec);
		return 2;
		}
	slen += mlen;
	EVP_CIPHER_CTX_cleanup(&ctx);
	p = sdec;

	sess = d2i_SSL_SESSION(NULL, &p, slen);
	OPENSSL_free(sdec);
	if (sess)
		{
		/* The session ID, if non-empty, is used by some clients to
		 * detect that the ticket has been accepted. So we copy it to
		 * the session structure. If it is empty set length to zero
		 * as required by standard.
		 */
		if (sesslen)
			memcpy(sess->session_id, sess_id, sesslen);
		sess->session_id_length = sesslen;
		*psess = sess;
		if (renew_ticket)
			return 4;
		else
			return 3;
		}
        ERR_clear_error();
	/* For session parse failure, indicate that we need to send a new
	 * ticket. */
	return 2;
	}

/* Tables to translate from NIDs to TLS v1.2 ids */

typedef struct 
	{
	int nid;
	int id;
	} tls12_lookup;

static const tls12_lookup tls12_md[] = {
	{NID_md5, TLSEXT_hash_md5},
	{NID_sha1, TLSEXT_hash_sha1},
	{NID_sha224, TLSEXT_hash_sha224},
	{NID_sha256, TLSEXT_hash_sha256},
	{NID_sha384, TLSEXT_hash_sha384},
	{NID_sha512, TLSEXT_hash_sha512}
};

static const tls12_lookup tls12_sig[] = {
	{EVP_PKEY_RSA, TLSEXT_signature_rsa},
	{EVP_PKEY_EC, TLSEXT_signature_ecdsa}
};

static int tls12_find_id(int nid, const tls12_lookup *table, size_t tlen)
	{
	size_t i;
	for (i = 0; i < tlen; i++)
		{
		if (table[i].nid == nid)
			return table[i].id;
		}
	return -1;
	}

static int tls12_find_nid(int id, const tls12_lookup *table, size_t tlen)
	{
	size_t i;
	for (i = 0; i < tlen; i++)
		{
		if ((table[i].id) == id)
			return table[i].nid;
		}
	return NID_undef;
	}

int tls12_get_sigandhash(unsigned char *p, const EVP_PKEY *pk, const EVP_MD *md)
	{
	int sig_id, md_id;
	if (!md)
		return 0;
	md_id = tls12_find_id(EVP_MD_type(md), tls12_md,
				sizeof(tls12_md)/sizeof(tls12_lookup));
	if (md_id == -1)
		return 0;
	sig_id = tls12_get_sigid(pk);
	if (sig_id == -1)
		return 0;
	p[0] = (unsigned char)md_id;
	p[1] = (unsigned char)sig_id;
	return 1;
	}

int tls12_get_sigid(const EVP_PKEY *pk)
	{
	return tls12_find_id(pk->type, tls12_sig,
				sizeof(tls12_sig)/sizeof(tls12_lookup));
	}

const EVP_MD *tls12_get_hash(unsigned char hash_alg)
	{
	switch(hash_alg)
		{
		case TLSEXT_hash_md5:
		return EVP_md5();
		case TLSEXT_hash_sha1:
		return EVP_sha1();
		case TLSEXT_hash_sha224:
		return EVP_sha224();

		case TLSEXT_hash_sha256:
		return EVP_sha256();
		case TLSEXT_hash_sha384:
		return EVP_sha384();

		case TLSEXT_hash_sha512:
		return EVP_sha512();
		default:
		return NULL;

		}
	}

static int tls12_get_pkey_idx(unsigned char sig_alg)
	{
	switch(sig_alg)
		{
	case TLSEXT_signature_rsa:
		return SSL_PKEY_RSA_SIGN;
	case TLSEXT_signature_ecdsa:
		return SSL_PKEY_ECC;
		}
	return -1;
	}

/* Convert TLS 1.2 signature algorithm extension values into NIDs */
static void tls1_lookup_sigalg(int *phash_nid, int *psign_nid,
			int *psignhash_nid, const unsigned char *data)
	{
	int sign_nid = 0, hash_nid = 0;
	if (!phash_nid && !psign_nid && !psignhash_nid)
		return;
	if (phash_nid || psignhash_nid)
		{
		hash_nid = tls12_find_nid(data[0], tls12_md,
					sizeof(tls12_md)/sizeof(tls12_lookup));
		if (phash_nid)
			*phash_nid = hash_nid;
		}
	if (psign_nid || psignhash_nid)
		{
		sign_nid = tls12_find_nid(data[1], tls12_sig,
					sizeof(tls12_sig)/sizeof(tls12_lookup));
		if (psign_nid)
			*psign_nid = sign_nid;
		}
	if (psignhash_nid)
		{
		if (sign_nid && hash_nid)
			OBJ_find_sigid_by_algs(psignhash_nid,
							hash_nid, sign_nid);
		else
			*psignhash_nid = NID_undef;
		}
	}
/* Given preference and allowed sigalgs set shared sigalgs */
static int tls12_do_shared_sigalgs(TLS_SIGALGS *shsig,
				const unsigned char *pref, size_t preflen,
				const unsigned char *allow, size_t allowlen)
	{
	const unsigned char *ptmp, *atmp;
	size_t i, j, nmatch = 0;
	for (i = 0, ptmp = pref; i < preflen; i+=2, ptmp+=2)
		{
		/* Skip disabled hashes or signature algorithms */
		if (tls12_get_hash(ptmp[0]) == NULL)
			continue;
		if (tls12_get_pkey_idx(ptmp[1]) == -1)
			continue;
		for (j = 0, atmp = allow; j < allowlen; j+=2, atmp+=2)
			{
			if (ptmp[0] == atmp[0] && ptmp[1] == atmp[1])
				{
				nmatch++;
				if (shsig)
					{
					shsig->rhash = ptmp[0];
					shsig->rsign = ptmp[1];
					tls1_lookup_sigalg(&shsig->hash_nid,
						&shsig->sign_nid,
						&shsig->signandhash_nid,
						ptmp);
					shsig++;
					}
				break;
				}
			}
		}
	return nmatch;
	}

/* Set shared signature algorithms for SSL structures */
static int tls1_set_shared_sigalgs(SSL *s)
	{
	const unsigned char *pref, *allow, *conf;
	size_t preflen, allowlen, conflen;
	size_t nmatch;
	TLS_SIGALGS *salgs = NULL;
	CERT *c = s->cert;
	if (c->shared_sigalgs)
		{
		OPENSSL_free(c->shared_sigalgs);
		c->shared_sigalgs = NULL;
		}
	/* If client use client signature algorithms if not NULL */
	if (!s->server && c->client_sigalgs)
		{
		conf = c->client_sigalgs;
		conflen = c->client_sigalgslen;
		}
	else if (c->conf_sigalgs)
		{
		conf = c->conf_sigalgs;
		conflen = c->conf_sigalgslen;
		}
	else
		conflen = tls12_get_psigalgs(s, &conf);
	if(s->options & SSL_OP_CIPHER_SERVER_PREFERENCE)
		{
		pref = conf;
		preflen = conflen;
		allow = c->peer_sigalgs;
		allowlen = c->peer_sigalgslen;
		}
	else
		{
		allow = conf;
		allowlen = conflen;
		pref = c->peer_sigalgs;
		preflen = c->peer_sigalgslen;
		}
	nmatch = tls12_do_shared_sigalgs(NULL, pref, preflen, allow, allowlen);
	if (!nmatch)
		return 1;
	salgs = OPENSSL_malloc(nmatch * sizeof(TLS_SIGALGS));
	if (!salgs)
		return 0;
	nmatch = tls12_do_shared_sigalgs(salgs, pref, preflen, allow, allowlen);
	c->shared_sigalgs = salgs;
	c->shared_sigalgslen = nmatch;
	return 1;
	}
		

/* Set preferred digest for each key type */

int tls1_process_sigalgs(SSL *s, const CBS *sigalgs)
	{
	int idx;
	size_t i;
	const EVP_MD *md;
	CERT *c = s->cert;
	TLS_SIGALGS *sigptr;

	/* Extension ignored for inappropriate versions */
	if (!SSL_USE_SIGALGS(s))
		return 1;
	/* Length must be even */
	if (CBS_len(sigalgs) % 2 != 0)
		return 0;
	/* Should never happen */
	if (!c)
		return 0;

	if (!CBS_stow(sigalgs, &c->peer_sigalgs, &c->peer_sigalgslen))
		return 0;

	tls1_set_shared_sigalgs(s);

#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL
	if (s->cert->cert_flags & SSL_CERT_FLAG_BROKEN_PROTOCOL)
		{
		/* Use first set signature preference to force message
		 * digest, ignoring any peer preferences.
		 */
		const unsigned char *sigs = NULL;
		if (s->server)
			sigs = c->conf_sigalgs;
		else
			sigs = c->client_sigalgs;
		if (sigs)
			{
			idx = tls12_get_pkey_idx(sigs[1]);
			md = tls12_get_hash(sigs[0]);
			c->pkeys[idx].digest = md;
			c->pkeys[idx].valid_flags = CERT_PKEY_EXPLICIT_SIGN;
			if (idx == SSL_PKEY_RSA_SIGN)
				{
				c->pkeys[SSL_PKEY_RSA_ENC].valid_flags = CERT_PKEY_EXPLICIT_SIGN;
				c->pkeys[SSL_PKEY_RSA_ENC].digest = md;
				}
			}
		}
#endif

	for (i = 0, sigptr = c->shared_sigalgs;
			i < c->shared_sigalgslen; i++, sigptr++)
		{
		idx = tls12_get_pkey_idx(sigptr->rsign);
		if (idx > 0 && c->pkeys[idx].digest == NULL)
			{
			md = tls12_get_hash(sigptr->rhash);
			c->pkeys[idx].digest = md;
			c->pkeys[idx].valid_flags = CERT_PKEY_EXPLICIT_SIGN;
			if (idx == SSL_PKEY_RSA_SIGN)
				{
				c->pkeys[SSL_PKEY_RSA_ENC].valid_flags = CERT_PKEY_EXPLICIT_SIGN;
				c->pkeys[SSL_PKEY_RSA_ENC].digest = md;
				}
			}

		}
	/* In strict mode leave unset digests as NULL to indicate we can't
	 * use the certificate for signing.
	 */
	if (!(s->cert->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT))
		{
		/* Set any remaining keys to default values. NOTE: if alg is
		 * not supported it stays as NULL.
	 	 */
		if (!c->pkeys[SSL_PKEY_RSA_SIGN].digest)
			{
			c->pkeys[SSL_PKEY_RSA_SIGN].digest = EVP_sha1();
			c->pkeys[SSL_PKEY_RSA_ENC].digest = EVP_sha1();
			}
		if (!c->pkeys[SSL_PKEY_ECC].digest)
			c->pkeys[SSL_PKEY_ECC].digest = EVP_sha1();
		}
	return 1;
	}


int SSL_get_sigalgs(SSL *s, int idx,
			int *psign, int *phash, int *psignhash,
			unsigned char *rsig, unsigned char *rhash)
	{
	const unsigned char *psig = s->cert->peer_sigalgs;
	if (psig == NULL)
		return 0;
	if (idx >= 0)
		{
		idx <<= 1;
		if (idx >= (int)s->cert->peer_sigalgslen)
			return 0;
		psig += idx;
		if (rhash)
			*rhash = psig[0];
		if (rsig)
			*rsig = psig[1];
		tls1_lookup_sigalg(phash, psign, psignhash, psig);
		}
	return s->cert->peer_sigalgslen / 2;
	}

int SSL_get_shared_sigalgs(SSL *s, int idx,
			int *psign, int *phash, int *psignhash,
			unsigned char *rsig, unsigned char *rhash)
	{
	TLS_SIGALGS *shsigalgs = s->cert->shared_sigalgs;
	if (!shsigalgs || idx >= (int)s->cert->shared_sigalgslen)
		return 0;
	shsigalgs += idx;
	if (phash)
		*phash = shsigalgs->hash_nid;
	if (psign)
		*psign = shsigalgs->sign_nid;
	if (psignhash)
		*psignhash = shsigalgs->signandhash_nid;
	if (rsig)
		*rsig = shsigalgs->rsign;
	if (rhash)
		*rhash = shsigalgs->rhash;
	return s->cert->shared_sigalgslen;
	}
	
/* tls1_channel_id_hash calculates the signed data for a Channel ID on the given
 * SSL connection and writes it to |md|. */
int
tls1_channel_id_hash(EVP_MD_CTX *md, SSL *s)
	{
	EVP_MD_CTX ctx;
	unsigned char temp_digest[EVP_MAX_MD_SIZE];
	unsigned temp_digest_len;
	int i;
	static const char kClientIDMagic[] = "TLS Channel ID signature";

	if (s->s3->handshake_buffer)
		if (!ssl3_digest_cached_records(s))
			return 0;

	EVP_DigestUpdate(md, kClientIDMagic, sizeof(kClientIDMagic));

	if (s->hit && s->s3->tlsext_channel_id_new)
		{
		static const char kResumptionMagic[] = "Resumption";
		EVP_DigestUpdate(md, kResumptionMagic,
				 sizeof(kResumptionMagic));
		if (s->session->original_handshake_hash_len == 0)
			return 0;
		EVP_DigestUpdate(md, s->session->original_handshake_hash,
				 s->session->original_handshake_hash_len);
		}

	EVP_MD_CTX_init(&ctx);
	for (i = 0; i < SSL_MAX_DIGEST; i++)
		{
		if (s->s3->handshake_dgst[i] == NULL)
			continue;
		EVP_MD_CTX_copy_ex(&ctx, s->s3->handshake_dgst[i]);
		EVP_DigestFinal_ex(&ctx, temp_digest, &temp_digest_len);
		EVP_DigestUpdate(md, temp_digest, temp_digest_len);
		}
	EVP_MD_CTX_cleanup(&ctx);

	return 1;
	}

/* tls1_record_handshake_hashes_for_channel_id records the current handshake
 * hashes in |s->session| so that Channel ID resumptions can sign that data. */
int tls1_record_handshake_hashes_for_channel_id(SSL *s)
	{
	int digest_len;
	/* This function should never be called for a resumed session because
	 * the handshake hashes that we wish to record are for the original,
	 * full handshake. */
	if (s->hit)
		return -1;
	/* It only makes sense to call this function if Channel IDs have been
	 * negotiated. */
	if (!s->s3->tlsext_channel_id_new)
		return -1;

	digest_len = tls1_handshake_digest(
		s, s->session->original_handshake_hash,
		sizeof(s->session->original_handshake_hash));
	if (digest_len < 0)
		return -1;

	s->session->original_handshake_hash_len = digest_len;

	return 1;
	}

int tls1_set_sigalgs(CERT *c, const int *psig_nids, size_t salglen, int client)
	{
	unsigned char *sigalgs, *sptr;
	int rhash, rsign;
	size_t i;
	if (salglen & 1)
		return 0;
	sigalgs = OPENSSL_malloc(salglen);
	if (sigalgs == NULL)
		return 0;
	for (i = 0, sptr = sigalgs; i < salglen; i+=2)
		{
		rhash = tls12_find_id(*psig_nids++, tls12_md,
					sizeof(tls12_md)/sizeof(tls12_lookup));
		rsign = tls12_find_id(*psig_nids++, tls12_sig,
				sizeof(tls12_sig)/sizeof(tls12_lookup));

		if (rhash == -1 || rsign == -1)
			goto err;
		*sptr++ = rhash;
		*sptr++ = rsign;
		}

	if (client)
		{
		if (c->client_sigalgs)
			OPENSSL_free(c->client_sigalgs);
		c->client_sigalgs = sigalgs;
		c->client_sigalgslen = salglen;
		}
	else
		{
		if (c->conf_sigalgs)
			OPENSSL_free(c->conf_sigalgs);
		c->conf_sigalgs = sigalgs;
		c->conf_sigalgslen = salglen;
		}

	return 1;

	err:
	OPENSSL_free(sigalgs);
	return 0;
	}

static int tls1_check_sig_alg(CERT *c, X509 *x, int default_nid)
	{
	int sig_nid;
	size_t i;
	if (default_nid == -1)
		return 1;
	sig_nid = X509_get_signature_nid(x);
	if (default_nid)
		return sig_nid == default_nid ? 1 : 0;
	for (i = 0; i < c->shared_sigalgslen; i++)
		if (sig_nid == c->shared_sigalgs[i].signandhash_nid)
			return 1;
	return 0;
	}
/* Check to see if a certificate issuer name matches list of CA names */
static int ssl_check_ca_name(STACK_OF(X509_NAME) *names, X509 *x)
	{
	X509_NAME *nm;
	int i;
	nm = X509_get_issuer_name(x);
	for (i = 0; i < sk_X509_NAME_num(names); i++)
		{
		if(!X509_NAME_cmp(nm, sk_X509_NAME_value(names, i)))
			return 1;
		}
	return 0;
	}

/* Check certificate chain is consistent with TLS extensions and is
 * usable by server. This servers two purposes: it allows users to 
 * check chains before passing them to the server and it allows the
 * server to check chains before attempting to use them.
 */

/* Flags which need to be set for a certificate when stict mode not set */

#define CERT_PKEY_VALID_FLAGS \
	(CERT_PKEY_EE_SIGNATURE|CERT_PKEY_EE_PARAM)
/* Strict mode flags */
#define CERT_PKEY_STRICT_FLAGS \
	 (CERT_PKEY_VALID_FLAGS|CERT_PKEY_CA_SIGNATURE|CERT_PKEY_CA_PARAM \
	 | CERT_PKEY_ISSUER_NAME|CERT_PKEY_CERT_TYPE)

int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain,
									int idx)
	{
	int i;
	int rv = 0;
	int check_flags = 0, strict_mode;
	CERT_PKEY *cpk = NULL;
	CERT *c = s->cert;
	/* idx == -1 means checking server chains */
	if (idx != -1)
		{
		/* idx == -2 means checking client certificate chains */
		if (idx == -2)
			{
			cpk = c->key;
			idx = cpk - c->pkeys;
			}
		else
			cpk = c->pkeys + idx;
		x = cpk->x509;
		pk = cpk->privatekey;
		chain = cpk->chain;
		strict_mode = c->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT;
		/* If no cert or key, forget it */
		if (!x || !pk)
			goto end;
#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL
		/* Allow any certificate to pass test */
		if (s->cert->cert_flags & SSL_CERT_FLAG_BROKEN_PROTOCOL)
			{
			rv = CERT_PKEY_STRICT_FLAGS|CERT_PKEY_EXPLICIT_SIGN|CERT_PKEY_VALID|CERT_PKEY_SIGN;
			cpk->valid_flags = rv;
			return rv;
			}
#endif
		}
	else
		{
		if (!x || !pk)
			goto end;
		idx = ssl_cert_type(x, pk);
		if (idx == -1)
			goto end;
		cpk = c->pkeys + idx;
		if (c->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT)
			check_flags = CERT_PKEY_STRICT_FLAGS;
		else
			check_flags = CERT_PKEY_VALID_FLAGS;
		strict_mode = 1;
		}

	/* Check all signature algorithms are consistent with
	 * signature algorithms extension if TLS 1.2 or later
	 * and strict mode.
	 */
	if (TLS1_get_version(s) >= TLS1_2_VERSION && strict_mode)
		{
		int default_nid;
		unsigned char rsign = 0;
		if (c->peer_sigalgs)
			default_nid = 0;
		/* If no sigalgs extension use defaults from RFC5246 */
		else
			{
			switch(idx)
				{	
			case SSL_PKEY_RSA_ENC:
			case SSL_PKEY_RSA_SIGN:
				rsign = TLSEXT_signature_rsa;
				default_nid = NID_sha1WithRSAEncryption;
				break;

			case SSL_PKEY_ECC:
				rsign = TLSEXT_signature_ecdsa;
				default_nid = NID_ecdsa_with_SHA1;
				break;

			default:
				default_nid = -1;
				break;
				}
			}
		/* If peer sent no signature algorithms extension and we
		 * have set preferred signature algorithms check we support
		 * sha1.
		 */
		if (default_nid > 0 && c->conf_sigalgs)
			{
			size_t j;
			const unsigned char *p = c->conf_sigalgs;
			for (j = 0; j < c->conf_sigalgslen; j += 2, p += 2)
				{
				if (p[0] == TLSEXT_hash_sha1 && p[1] == rsign)
					break;
				}
			if (j == c->conf_sigalgslen)
				{
				if (check_flags)
					goto skip_sigs;
				else
					goto end;
				}
			}
		/* Check signature algorithm of each cert in chain */
		if (!tls1_check_sig_alg(c, x, default_nid))
			{
			if (!check_flags) goto end;
			}
		else
			rv |= CERT_PKEY_EE_SIGNATURE;
		rv |= CERT_PKEY_CA_SIGNATURE;
		for (i = 0; i < sk_X509_num(chain); i++)
			{
			if (!tls1_check_sig_alg(c, sk_X509_value(chain, i),
							default_nid))
				{
				if (check_flags)
					{
					rv &= ~CERT_PKEY_CA_SIGNATURE;
					break;
					}
				else
					goto end;
				}
			}
		}
	/* Else not TLS 1.2, so mark EE and CA signing algorithms OK */
	else if(check_flags)
		rv |= CERT_PKEY_EE_SIGNATURE|CERT_PKEY_CA_SIGNATURE;
	skip_sigs:
	/* Check cert parameters are consistent */
	if (tls1_check_cert_param(s, x, check_flags ? 1 : 2))
		rv |= CERT_PKEY_EE_PARAM;
	else if (!check_flags)
		goto end;
	if (!s->server)
		rv |= CERT_PKEY_CA_PARAM;
	/* In strict mode check rest of chain too */
	else if (strict_mode)
		{
		rv |= CERT_PKEY_CA_PARAM;
		for (i = 0; i < sk_X509_num(chain); i++)
			{
			X509 *ca = sk_X509_value(chain, i);
			if (!tls1_check_cert_param(s, ca, 0))
				{
				if (check_flags)
					{
					rv &= ~CERT_PKEY_CA_PARAM;
					break;
					}
				else
					goto end;
				}
			}
		}
	if (!s->server && strict_mode)
		{
		STACK_OF(X509_NAME) *ca_dn;
		uint8_t check_type = 0;
		switch (pk->type)
			{
		case EVP_PKEY_RSA:
			check_type = TLS_CT_RSA_SIGN;
			break;
		case EVP_PKEY_EC:
			check_type = TLS_CT_ECDSA_SIGN;
			break;
			}
		if (check_type)
			{
			if (s->s3->tmp.certificate_types &&
				memchr(s->s3->tmp.certificate_types, check_type, s->s3->tmp.num_certificate_types))
				{
					rv |= CERT_PKEY_CERT_TYPE;
				}
			if (!(rv & CERT_PKEY_CERT_TYPE) && !check_flags)
				goto end;
			}
		else
			rv |= CERT_PKEY_CERT_TYPE;


		ca_dn = s->s3->tmp.ca_names;

		if (!sk_X509_NAME_num(ca_dn))
			rv |= CERT_PKEY_ISSUER_NAME;

		if (!(rv & CERT_PKEY_ISSUER_NAME))
			{
			if (ssl_check_ca_name(ca_dn, x))
				rv |= CERT_PKEY_ISSUER_NAME;
			}
		if (!(rv & CERT_PKEY_ISSUER_NAME))
			{
			for (i = 0; i < sk_X509_num(chain); i++)
				{
				X509 *xtmp = sk_X509_value(chain, i);
				if (ssl_check_ca_name(ca_dn, xtmp))
					{
					rv |= CERT_PKEY_ISSUER_NAME;
					break;
					}
				}
			}
		if (!check_flags && !(rv & CERT_PKEY_ISSUER_NAME))
			goto end;
		}
	else
		rv |= CERT_PKEY_ISSUER_NAME|CERT_PKEY_CERT_TYPE;

	if (!check_flags || (rv & check_flags) == check_flags)
		rv |= CERT_PKEY_VALID;

	end:

	if (TLS1_get_version(s) >= TLS1_2_VERSION)
		{
		if (cpk->valid_flags & CERT_PKEY_EXPLICIT_SIGN)
			rv |= CERT_PKEY_EXPLICIT_SIGN|CERT_PKEY_SIGN;
		else if (cpk->digest)
			rv |= CERT_PKEY_SIGN;
		}
	else
		rv |= CERT_PKEY_SIGN|CERT_PKEY_EXPLICIT_SIGN;

	/* When checking a CERT_PKEY structure all flags are irrelevant
	 * if the chain is invalid.
	 */
	if (!check_flags)
		{
		if (rv & CERT_PKEY_VALID)
			cpk->valid_flags = rv;
		else
			{
			/* Preserve explicit sign flag, clear rest */
			cpk->valid_flags &= CERT_PKEY_EXPLICIT_SIGN;
			return 0;
			}
		}
	return rv;
	}

/* Set validity of certificates in an SSL structure */
void tls1_set_cert_validity(SSL *s)
	{
	tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_RSA_ENC);
	tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_RSA_SIGN);
	tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_ECC);
	}
/* User level utiity function to check a chain is suitable */
int SSL_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain)
	{
	return tls1_check_chain(s, x, pk, chain, -1);
	}

