static int ssl3_get_client_key_exchange(SSL *s)
	{
	int i,al,ok;
	long n;
	unsigned long l;
	unsigned char *p;
#ifndef OPENSSL_NO_RSA
	RSA *rsa=NULL;
	EVP_PKEY *pkey=NULL;
#endif
#ifndef OPENSSL_NO_DH
	BIGNUM *pub=NULL;
	DH *dh_srvr;
#endif
#ifndef OPENSSL_NO_KRB5
        KSSL_ERR kssl_err;
#endif
#ifndef OPENSSL_NO_ECDH
	EC_KEY *srvr_ecdh = NULL;
	EVP_PKEY *clnt_pub_pkey = NULL;
	EC_POINT *clnt_ecpoint = NULL;
	BN_CTX *bn_ctx = NULL;
#endif
	n=ssl3_get_message(s,
		SSL3_ST_SR_KEY_EXCH_A,
		SSL3_ST_SR_KEY_EXCH_B,
		SSL3_MT_CLIENT_KEY_EXCHANGE,
		2048,
		&ok);
	if (!ok) return((int)n);
	p=(unsigned char *)s->init_msg;
	l=s->s3->tmp.new_cipher->algorithms;
#ifndef OPENSSL_NO_RSA
	if (l & SSL_kRSA)
		{
		if (s->s3->tmp.use_rsa_tmp)
			{
			if ((s->cert != NULL) && (s->cert->rsa_tmp != NULL))
				rsa=s->cert->rsa_tmp;
			if (rsa == NULL)
				{
				al=SSL_AD_HANDSHAKE_FAILURE;
				SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_MISSING_TMP_RSA_PKEY);
				goto f_err;
				}
			}
		else
			{
			pkey=s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey;
			if (	(pkey == NULL) ||
				(pkey->type != EVP_PKEY_RSA) ||
				(pkey->pkey.rsa == NULL))
				{
				al=SSL_AD_HANDSHAKE_FAILURE;
				SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_MISSING_RSA_CERTIFICATE);
				goto f_err;
				}
			rsa=pkey->pkey.rsa;
			}
		if (s->version > SSL3_VERSION)
			{
			n2s(p,i);
			if (n != i+2)
				{
				if (!(s->options & SSL_OP_TLS_D5_BUG))
					{
					SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG);
					goto err;
					}
				else
					p-=2;
				}
			else
				n=i;
			}
		i=RSA_private_decrypt((int)n,p,p,rsa,RSA_PKCS1_PADDING);
		al = -1;
		if (i != SSL_MAX_MASTER_KEY_LENGTH)
			{
			al=SSL_AD_DECODE_ERROR;
			}
		if ((al == -1) && !((p[0] == (s->client_version>>8)) && (p[1] == (s->client_version & 0xff))))
			{
			if (!((s->options & SSL_OP_TLS_ROLLBACK_BUG) &&
				(p[0] == (s->version>>8)) && (p[1] == (s->version & 0xff))))
				{
				al=SSL_AD_DECODE_ERROR;
				}
			}
		if (al != -1)
			{
			ERR_clear_error();
			i = SSL_MAX_MASTER_KEY_LENGTH;
			p[0] = s->client_version >> 8;
			p[1] = s->client_version & 0xff;
			RAND_pseudo_bytes(p+2, i-2);
			}
		s->session->master_key_length=
			s->method->ssl3_enc->generate_master_secret(s,
				s->session->master_key,
				p,i);
		OPENSSL_cleanse(p,i);
		}
	else
#endif
#ifndef OPENSSL_NO_DH
		if (l & (SSL_kEDH|SSL_kDHr|SSL_kDHd))
		{
		n2s(p,i);
		if (n != i+2)
			{
			if (!(s->options & SSL_OP_SSLEAY_080_CLIENT_DH_BUG))
				{
				SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG);
				goto err;
				}
			else
				{
				p-=2;
				i=(int)n;
				}
			}
		if (n == 0L)
			{
			al=SSL_AD_HANDSHAKE_FAILURE;
			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_UNABLE_TO_DECODE_DH_CERTS);
			goto f_err;
			}
		else
			{
			if (s->s3->tmp.dh == NULL)
				{
				al=SSL_AD_HANDSHAKE_FAILURE;
				SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_MISSING_TMP_DH_KEY);
				goto f_err;
				}
			else
				dh_srvr=s->s3->tmp.dh;
			}
		pub=BN_bin2bn(p,i,NULL);
		if (pub == NULL)
			{
			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_BN_LIB);
			goto err;
			}
		i=DH_compute_key(p,pub,dh_srvr);
		if (i <= 0)
			{
			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,ERR_R_DH_LIB);
			goto err;
			}
		DH_free(s->s3->tmp.dh);
		s->s3->tmp.dh=NULL;
		BN_clear_free(pub);
		pub=NULL;
		s->session->master_key_length=
			s->method->ssl3_enc->generate_master_secret(s,
				s->session->master_key,p,i);
		OPENSSL_cleanse(p,i);
		}
	else
#endif
#ifndef OPENSSL_NO_KRB5
        if (l & SSL_kKRB5)
                {
                krb5_error_code		krb5rc;
		krb5_data		enc_ticket;
		krb5_data		authenticator;
		krb5_data		enc_pms;
                KSSL_CTX		*kssl_ctx = s->kssl_ctx;
		EVP_CIPHER_CTX		ciph_ctx;
		EVP_CIPHER		*enc = NULL;
		unsigned char		iv[EVP_MAX_IV_LENGTH];
		unsigned char		pms[SSL_MAX_MASTER_KEY_LENGTH
                                               + EVP_MAX_BLOCK_LENGTH];
		int                     padl, outl;
		krb5_timestamp		authtime = 0;
		krb5_ticket_times	ttimes;
		EVP_CIPHER_CTX_init(&ciph_ctx);
                if (!kssl_ctx)  kssl_ctx = kssl_ctx_new();
		n2s(p,i);
		enc_ticket.length = i;
		enc_ticket.data = (char *)p;
		p+=enc_ticket.length;
		n2s(p,i);
		authenticator.length = i;
		authenticator.data = (char *)p;
		p+=authenticator.length;
		n2s(p,i);
		enc_pms.length = i;
		enc_pms.data = (char *)p;
		p+=enc_pms.length;
		if(enc_pms.length > sizeof pms)
			{
			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
			       SSL_R_DATA_LENGTH_TOO_LONG);
			goto err;
			}
		if (n != enc_ticket.length + authenticator.length +
						enc_pms.length + 6)
			{
			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
				SSL_R_DATA_LENGTH_TOO_LONG);
			goto err;
			}
                if ((krb5rc = kssl_sget_tkt(kssl_ctx, &enc_ticket, &ttimes,
					&kssl_err)) != 0)
                        {
#ifdef KSSL_DEBUG
                        printf("kssl_sget_tkt rtn %d [%d]\n",
                                krb5rc, kssl_err.reason);
                        if (kssl_err.text)
                                printf("kssl_err text= %s\n", kssl_err.text);
#endif
                        SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
                                kssl_err.reason);
                        goto err;
                        }
		if ((krb5rc = kssl_check_authent(kssl_ctx, &authenticator,
					&authtime, &kssl_err)) != 0)
			{
#ifdef KSSL_DEBUG
                        printf("kssl_check_authent rtn %d [%d]\n",
                                krb5rc, kssl_err.reason);
                        if (kssl_err.text)
                                printf("kssl_err text= %s\n", kssl_err.text);
#endif
                        SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
                                kssl_err.reason);
                        goto err;
			}
		if ((krb5rc = kssl_validate_times(authtime, &ttimes)) != 0)
			{
			SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, krb5rc);
                        goto err;
			}
#ifdef KSSL_DEBUG
                kssl_ctx_show(kssl_ctx);
#endif
		enc = kssl_map_enc(kssl_ctx->enctype);
                if (enc == NULL)
                    goto err;
		memset(iv, 0, sizeof iv);
		if (!EVP_DecryptInit_ex(&ciph_ctx,enc,NULL,kssl_ctx->key,iv))
			{
			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
				SSL_R_DECRYPTION_FAILED);
			goto err;
			}
		if (!EVP_DecryptUpdate(&ciph_ctx, pms,&outl,
					(unsigned char *)enc_pms.data, enc_pms.length))
			{
			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
				SSL_R_DECRYPTION_FAILED);
			goto err;
			}
		if (outl > SSL_MAX_MASTER_KEY_LENGTH)
			{
			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
				SSL_R_DATA_LENGTH_TOO_LONG);
			goto err;
			}
		if (!EVP_DecryptFinal_ex(&ciph_ctx,&(pms[outl]),&padl))
			{
			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
				SSL_R_DECRYPTION_FAILED);
			goto err;
			}
		outl += padl;
		if (outl > SSL_MAX_MASTER_KEY_LENGTH)
			{
			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
				SSL_R_DATA_LENGTH_TOO_LONG);
			goto err;
			}
		EVP_CIPHER_CTX_cleanup(&ciph_ctx);
                s->session->master_key_length=
                        s->method->ssl3_enc->generate_master_secret(s,
                                s->session->master_key, pms, outl);
                if (kssl_ctx->client_princ)
                        {
                        int len = strlen(kssl_ctx->client_princ);
                        if ( len < SSL_MAX_KRB5_PRINCIPAL_LENGTH )
                                {
                                s->session->krb5_client_princ_len = len;
                                memcpy(s->session->krb5_client_princ,kssl_ctx->client_princ,len);
                                }
                        }
                }
	else
#endif
#ifndef OPENSSL_NO_ECDH
		if ((l & SSL_kECDH) || (l & SSL_kECDHE))
		{
		int ret = 1;
		int field_size = 0;
		if ((srvr_ecdh = EC_KEY_new()) == NULL)
			{
                	SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
			    ERR_R_MALLOC_FAILURE);
                	goto err;
			}
		if (l & SSL_kECDH)
			{
			srvr_ecdh->group = s->cert->key->privatekey-> \
			    pkey.eckey->group;
			srvr_ecdh->priv_key = s->cert->key->privatekey-> \
			    pkey.eckey->priv_key;
			}
		else
			{
			srvr_ecdh->group = s->s3->tmp.ecdh->group;
			srvr_ecdh->priv_key = s->s3->tmp.ecdh->priv_key;
			}
		if ((clnt_ecpoint = EC_POINT_new(srvr_ecdh->group))
		    == NULL)
			{
			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
			    ERR_R_MALLOC_FAILURE);
			goto err;
			}
                if (n == 0L)
                        {
			 if (l & SSL_kECDHE)
				 {
				 al=SSL_AD_HANDSHAKE_FAILURE;
				 SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_MISSING_TMP_ECDH_KEY);
				 goto f_err;
				 }
                        if (((clnt_pub_pkey=X509_get_pubkey(s->session->peer))
			    == NULL) ||
			    (clnt_pub_pkey->type != EVP_PKEY_EC))
                        	{
                           	al=SSL_AD_HANDSHAKE_FAILURE;
                           	SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
				    SSL_R_UNABLE_TO_DECODE_ECDH_CERTS);
                           	goto f_err;
                           	}
			EC_POINT_copy(clnt_ecpoint,
			    clnt_pub_pkey->pkey.eckey->pub_key);
                        ret = 2;
                        }
                else
                        {
			if ((bn_ctx = BN_CTX_new()) == NULL)
				{
				SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
				    ERR_R_MALLOC_FAILURE);
				goto err;
				}
                        i = *p;
			p += 1;
                        if (EC_POINT_oct2point(srvr_ecdh->group,
			    clnt_ecpoint, p, i, bn_ctx) == 0)
				{
				SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
				    ERR_R_EC_LIB);
				goto err;
				}
                        p=(unsigned char *)s->init_buf->data;
                        }
		field_size = EC_GROUP_get_degree(srvr_ecdh->group);
		if (field_size <= 0)
			{
			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
			       ERR_R_ECDH_LIB);
			goto err;
			}
		if (field_size <= 24 * 8)
		    i = ECDH_compute_key(p, KDF1_SHA1_len, clnt_ecpoint, srvr_ecdh, KDF1_SHA1);
		else
		    i = ECDH_compute_key(p, (field_size+7)/8, clnt_ecpoint, srvr_ecdh, NULL);
                if (i <= 0)
                        {
                        SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
			    ERR_R_ECDH_LIB);
                        goto err;
                        }
		EVP_PKEY_free(clnt_pub_pkey);
		EC_POINT_free(clnt_ecpoint);
		if (srvr_ecdh != NULL)
			{
			srvr_ecdh->priv_key = NULL;
			srvr_ecdh->group = NULL;
			EC_KEY_free(srvr_ecdh);
			}
		BN_CTX_free(bn_ctx);
                s->session->master_key_length = s->method->ssl3_enc-> \
		    generate_master_secret(s, s->session->master_key, p, i);
                OPENSSL_cleanse(p, i);
                return (ret);
		}
	else
#endif
		{
		al=SSL_AD_HANDSHAKE_FAILURE;
		SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
				SSL_R_UNKNOWN_CIPHER_TYPE);
		goto f_err;
		}
	return(1);
f_err:
	ssl3_send_alert(s,SSL3_AL_FATAL,al);
#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_ECDH)
err:
#endif
#ifndef OPENSSL_NO_ECDH
	EVP_PKEY_free(clnt_pub_pkey);
	EC_POINT_free(clnt_ecpoint);
	if (srvr_ecdh != NULL)
		{
		srvr_ecdh->priv_key = NULL;
		srvr_ecdh->group = NULL;
		EC_KEY_free(srvr_ecdh);
		}
	BN_CTX_free(bn_ctx);
#endif
	return(-1);
	}
['static int ssl3_get_client_key_exchange(SSL *s)\n\t{\n\tint i,al,ok;\n\tlong n;\n\tunsigned long l;\n\tunsigned char *p;\n#ifndef OPENSSL_NO_RSA\n\tRSA *rsa=NULL;\n\tEVP_PKEY *pkey=NULL;\n#endif\n#ifndef OPENSSL_NO_DH\n\tBIGNUM *pub=NULL;\n\tDH *dh_srvr;\n#endif\n#ifndef OPENSSL_NO_KRB5\n        KSSL_ERR kssl_err;\n#endif\n#ifndef OPENSSL_NO_ECDH\n\tEC_KEY *srvr_ecdh = NULL;\n\tEVP_PKEY *clnt_pub_pkey = NULL;\n\tEC_POINT *clnt_ecpoint = NULL;\n\tBN_CTX *bn_ctx = NULL;\n#endif\n\tn=ssl3_get_message(s,\n\t\tSSL3_ST_SR_KEY_EXCH_A,\n\t\tSSL3_ST_SR_KEY_EXCH_B,\n\t\tSSL3_MT_CLIENT_KEY_EXCHANGE,\n\t\t2048,\n\t\t&ok);\n\tif (!ok) return((int)n);\n\tp=(unsigned char *)s->init_msg;\n\tl=s->s3->tmp.new_cipher->algorithms;\n#ifndef OPENSSL_NO_RSA\n\tif (l & SSL_kRSA)\n\t\t{\n\t\tif (s->s3->tmp.use_rsa_tmp)\n\t\t\t{\n\t\t\tif ((s->cert != NULL) && (s->cert->rsa_tmp != NULL))\n\t\t\t\trsa=s->cert->rsa_tmp;\n\t\t\tif (rsa == NULL)\n\t\t\t\t{\n\t\t\t\tal=SSL_AD_HANDSHAKE_FAILURE;\n\t\t\t\tSSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_MISSING_TMP_RSA_PKEY);\n\t\t\t\tgoto f_err;\n\t\t\t\t}\n\t\t\t}\n\t\telse\n\t\t\t{\n\t\t\tpkey=s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey;\n\t\t\tif (\t(pkey == NULL) ||\n\t\t\t\t(pkey->type != EVP_PKEY_RSA) ||\n\t\t\t\t(pkey->pkey.rsa == NULL))\n\t\t\t\t{\n\t\t\t\tal=SSL_AD_HANDSHAKE_FAILURE;\n\t\t\t\tSSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_MISSING_RSA_CERTIFICATE);\n\t\t\t\tgoto f_err;\n\t\t\t\t}\n\t\t\trsa=pkey->pkey.rsa;\n\t\t\t}\n\t\tif (s->version > SSL3_VERSION)\n\t\t\t{\n\t\t\tn2s(p,i);\n\t\t\tif (n != i+2)\n\t\t\t\t{\n\t\t\t\tif (!(s->options & SSL_OP_TLS_D5_BUG))\n\t\t\t\t\t{\n\t\t\t\t\tSSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG);\n\t\t\t\t\tgoto err;\n\t\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\tp-=2;\n\t\t\t\t}\n\t\t\telse\n\t\t\t\tn=i;\n\t\t\t}\n\t\ti=RSA_private_decrypt((int)n,p,p,rsa,RSA_PKCS1_PADDING);\n\t\tal = -1;\n\t\tif (i != SSL_MAX_MASTER_KEY_LENGTH)\n\t\t\t{\n\t\t\tal=SSL_AD_DECODE_ERROR;\n\t\t\t}\n\t\tif ((al == -1) && !((p[0] == (s->client_version>>8)) && (p[1] == (s->client_version & 0xff))))\n\t\t\t{\n\t\t\tif (!((s->options & SSL_OP_TLS_ROLLBACK_BUG) &&\n\t\t\t\t(p[0] == (s->version>>8)) && (p[1] == (s->version & 0xff))))\n\t\t\t\t{\n\t\t\t\tal=SSL_AD_DECODE_ERROR;\n\t\t\t\t}\n\t\t\t}\n\t\tif (al != -1)\n\t\t\t{\n\t\t\tERR_clear_error();\n\t\t\ti = SSL_MAX_MASTER_KEY_LENGTH;\n\t\t\tp[0] = s->client_version >> 8;\n\t\t\tp[1] = s->client_version & 0xff;\n\t\t\tRAND_pseudo_bytes(p+2, i-2);\n\t\t\t}\n\t\ts->session->master_key_length=\n\t\t\ts->method->ssl3_enc->generate_master_secret(s,\n\t\t\t\ts->session->master_key,\n\t\t\t\tp,i);\n\t\tOPENSSL_cleanse(p,i);\n\t\t}\n\telse\n#endif\n#ifndef OPENSSL_NO_DH\n\t\tif (l & (SSL_kEDH|SSL_kDHr|SSL_kDHd))\n\t\t{\n\t\tn2s(p,i);\n\t\tif (n != i+2)\n\t\t\t{\n\t\t\tif (!(s->options & SSL_OP_SSLEAY_080_CLIENT_DH_BUG))\n\t\t\t\t{\n\t\t\t\tSSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG);\n\t\t\t\tgoto err;\n\t\t\t\t}\n\t\t\telse\n\t\t\t\t{\n\t\t\t\tp-=2;\n\t\t\t\ti=(int)n;\n\t\t\t\t}\n\t\t\t}\n\t\tif (n == 0L)\n\t\t\t{\n\t\t\tal=SSL_AD_HANDSHAKE_FAILURE;\n\t\t\tSSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_UNABLE_TO_DECODE_DH_CERTS);\n\t\t\tgoto f_err;\n\t\t\t}\n\t\telse\n\t\t\t{\n\t\t\tif (s->s3->tmp.dh == NULL)\n\t\t\t\t{\n\t\t\t\tal=SSL_AD_HANDSHAKE_FAILURE;\n\t\t\t\tSSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_MISSING_TMP_DH_KEY);\n\t\t\t\tgoto f_err;\n\t\t\t\t}\n\t\t\telse\n\t\t\t\tdh_srvr=s->s3->tmp.dh;\n\t\t\t}\n\t\tpub=BN_bin2bn(p,i,NULL);\n\t\tif (pub == NULL)\n\t\t\t{\n\t\t\tSSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_BN_LIB);\n\t\t\tgoto err;\n\t\t\t}\n\t\ti=DH_compute_key(p,pub,dh_srvr);\n\t\tif (i <= 0)\n\t\t\t{\n\t\t\tSSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,ERR_R_DH_LIB);\n\t\t\tgoto err;\n\t\t\t}\n\t\tDH_free(s->s3->tmp.dh);\n\t\ts->s3->tmp.dh=NULL;\n\t\tBN_clear_free(pub);\n\t\tpub=NULL;\n\t\ts->session->master_key_length=\n\t\t\ts->method->ssl3_enc->generate_master_secret(s,\n\t\t\t\ts->session->master_key,p,i);\n\t\tOPENSSL_cleanse(p,i);\n\t\t}\n\telse\n#endif\n#ifndef OPENSSL_NO_KRB5\n        if (l & SSL_kKRB5)\n                {\n                krb5_error_code\t\tkrb5rc;\n\t\tkrb5_data\t\tenc_ticket;\n\t\tkrb5_data\t\tauthenticator;\n\t\tkrb5_data\t\tenc_pms;\n                KSSL_CTX\t\t*kssl_ctx = s->kssl_ctx;\n\t\tEVP_CIPHER_CTX\t\tciph_ctx;\n\t\tEVP_CIPHER\t\t*enc = NULL;\n\t\tunsigned char\t\tiv[EVP_MAX_IV_LENGTH];\n\t\tunsigned char\t\tpms[SSL_MAX_MASTER_KEY_LENGTH\n                                               + EVP_MAX_BLOCK_LENGTH];\n\t\tint                     padl, outl;\n\t\tkrb5_timestamp\t\tauthtime = 0;\n\t\tkrb5_ticket_times\tttimes;\n\t\tEVP_CIPHER_CTX_init(&ciph_ctx);\n                if (!kssl_ctx)  kssl_ctx = kssl_ctx_new();\n\t\tn2s(p,i);\n\t\tenc_ticket.length = i;\n\t\tenc_ticket.data = (char *)p;\n\t\tp+=enc_ticket.length;\n\t\tn2s(p,i);\n\t\tauthenticator.length = i;\n\t\tauthenticator.data = (char *)p;\n\t\tp+=authenticator.length;\n\t\tn2s(p,i);\n\t\tenc_pms.length = i;\n\t\tenc_pms.data = (char *)p;\n\t\tp+=enc_pms.length;\n\t\tif(enc_pms.length > sizeof pms)\n\t\t\t{\n\t\t\tSSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,\n\t\t\t       SSL_R_DATA_LENGTH_TOO_LONG);\n\t\t\tgoto err;\n\t\t\t}\n\t\tif (n != enc_ticket.length + authenticator.length +\n\t\t\t\t\t\tenc_pms.length + 6)\n\t\t\t{\n\t\t\tSSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,\n\t\t\t\tSSL_R_DATA_LENGTH_TOO_LONG);\n\t\t\tgoto err;\n\t\t\t}\n                if ((krb5rc = kssl_sget_tkt(kssl_ctx, &enc_ticket, &ttimes,\n\t\t\t\t\t&kssl_err)) != 0)\n                        {\n#ifdef KSSL_DEBUG\n                        printf("kssl_sget_tkt rtn %d [%d]\\n",\n                                krb5rc, kssl_err.reason);\n                        if (kssl_err.text)\n                                printf("kssl_err text= %s\\n", kssl_err.text);\n#endif\n                        SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,\n                                kssl_err.reason);\n                        goto err;\n                        }\n\t\tif ((krb5rc = kssl_check_authent(kssl_ctx, &authenticator,\n\t\t\t\t\t&authtime, &kssl_err)) != 0)\n\t\t\t{\n#ifdef KSSL_DEBUG\n                        printf("kssl_check_authent rtn %d [%d]\\n",\n                                krb5rc, kssl_err.reason);\n                        if (kssl_err.text)\n                                printf("kssl_err text= %s\\n", kssl_err.text);\n#endif\n                        SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,\n                                kssl_err.reason);\n                        goto err;\n\t\t\t}\n\t\tif ((krb5rc = kssl_validate_times(authtime, &ttimes)) != 0)\n\t\t\t{\n\t\t\tSSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, krb5rc);\n                        goto err;\n\t\t\t}\n#ifdef KSSL_DEBUG\n                kssl_ctx_show(kssl_ctx);\n#endif\n\t\tenc = kssl_map_enc(kssl_ctx->enctype);\n                if (enc == NULL)\n                    goto err;\n\t\tmemset(iv, 0, sizeof iv);\n\t\tif (!EVP_DecryptInit_ex(&ciph_ctx,enc,NULL,kssl_ctx->key,iv))\n\t\t\t{\n\t\t\tSSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,\n\t\t\t\tSSL_R_DECRYPTION_FAILED);\n\t\t\tgoto err;\n\t\t\t}\n\t\tif (!EVP_DecryptUpdate(&ciph_ctx, pms,&outl,\n\t\t\t\t\t(unsigned char *)enc_pms.data, enc_pms.length))\n\t\t\t{\n\t\t\tSSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,\n\t\t\t\tSSL_R_DECRYPTION_FAILED);\n\t\t\tgoto err;\n\t\t\t}\n\t\tif (outl > SSL_MAX_MASTER_KEY_LENGTH)\n\t\t\t{\n\t\t\tSSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,\n\t\t\t\tSSL_R_DATA_LENGTH_TOO_LONG);\n\t\t\tgoto err;\n\t\t\t}\n\t\tif (!EVP_DecryptFinal_ex(&ciph_ctx,&(pms[outl]),&padl))\n\t\t\t{\n\t\t\tSSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,\n\t\t\t\tSSL_R_DECRYPTION_FAILED);\n\t\t\tgoto err;\n\t\t\t}\n\t\toutl += padl;\n\t\tif (outl > SSL_MAX_MASTER_KEY_LENGTH)\n\t\t\t{\n\t\t\tSSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,\n\t\t\t\tSSL_R_DATA_LENGTH_TOO_LONG);\n\t\t\tgoto err;\n\t\t\t}\n\t\tEVP_CIPHER_CTX_cleanup(&ciph_ctx);\n                s->session->master_key_length=\n                        s->method->ssl3_enc->generate_master_secret(s,\n                                s->session->master_key, pms, outl);\n                if (kssl_ctx->client_princ)\n                        {\n                        int len = strlen(kssl_ctx->client_princ);\n                        if ( len < SSL_MAX_KRB5_PRINCIPAL_LENGTH )\n                                {\n                                s->session->krb5_client_princ_len = len;\n                                memcpy(s->session->krb5_client_princ,kssl_ctx->client_princ,len);\n                                }\n                        }\n                }\n\telse\n#endif\n#ifndef OPENSSL_NO_ECDH\n\t\tif ((l & SSL_kECDH) || (l & SSL_kECDHE))\n\t\t{\n\t\tint ret = 1;\n\t\tint field_size = 0;\n\t\tif ((srvr_ecdh = EC_KEY_new()) == NULL)\n\t\t\t{\n                \tSSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,\n\t\t\t    ERR_R_MALLOC_FAILURE);\n                \tgoto err;\n\t\t\t}\n\t\tif (l & SSL_kECDH)\n\t\t\t{\n\t\t\tsrvr_ecdh->group = s->cert->key->privatekey-> \\\n\t\t\t    pkey.eckey->group;\n\t\t\tsrvr_ecdh->priv_key = s->cert->key->privatekey-> \\\n\t\t\t    pkey.eckey->priv_key;\n\t\t\t}\n\t\telse\n\t\t\t{\n\t\t\tsrvr_ecdh->group = s->s3->tmp.ecdh->group;\n\t\t\tsrvr_ecdh->priv_key = s->s3->tmp.ecdh->priv_key;\n\t\t\t}\n\t\tif ((clnt_ecpoint = EC_POINT_new(srvr_ecdh->group))\n\t\t    == NULL)\n\t\t\t{\n\t\t\tSSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,\n\t\t\t    ERR_R_MALLOC_FAILURE);\n\t\t\tgoto err;\n\t\t\t}\n                if (n == 0L)\n                        {\n\t\t\t if (l & SSL_kECDHE)\n\t\t\t\t {\n\t\t\t\t al=SSL_AD_HANDSHAKE_FAILURE;\n\t\t\t\t SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_MISSING_TMP_ECDH_KEY);\n\t\t\t\t goto f_err;\n\t\t\t\t }\n                        if (((clnt_pub_pkey=X509_get_pubkey(s->session->peer))\n\t\t\t    == NULL) ||\n\t\t\t    (clnt_pub_pkey->type != EVP_PKEY_EC))\n                        \t{\n                           \tal=SSL_AD_HANDSHAKE_FAILURE;\n                           \tSSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,\n\t\t\t\t    SSL_R_UNABLE_TO_DECODE_ECDH_CERTS);\n                           \tgoto f_err;\n                           \t}\n\t\t\tEC_POINT_copy(clnt_ecpoint,\n\t\t\t    clnt_pub_pkey->pkey.eckey->pub_key);\n                        ret = 2;\n                        }\n                else\n                        {\n\t\t\tif ((bn_ctx = BN_CTX_new()) == NULL)\n\t\t\t\t{\n\t\t\t\tSSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,\n\t\t\t\t    ERR_R_MALLOC_FAILURE);\n\t\t\t\tgoto err;\n\t\t\t\t}\n                        i = *p;\n\t\t\tp += 1;\n                        if (EC_POINT_oct2point(srvr_ecdh->group,\n\t\t\t    clnt_ecpoint, p, i, bn_ctx) == 0)\n\t\t\t\t{\n\t\t\t\tSSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,\n\t\t\t\t    ERR_R_EC_LIB);\n\t\t\t\tgoto err;\n\t\t\t\t}\n                        p=(unsigned char *)s->init_buf->data;\n                        }\n\t\tfield_size = EC_GROUP_get_degree(srvr_ecdh->group);\n\t\tif (field_size <= 0)\n\t\t\t{\n\t\t\tSSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,\n\t\t\t       ERR_R_ECDH_LIB);\n\t\t\tgoto err;\n\t\t\t}\n\t\tif (field_size <= 24 * 8)\n\t\t    i = ECDH_compute_key(p, KDF1_SHA1_len, clnt_ecpoint, srvr_ecdh, KDF1_SHA1);\n\t\telse\n\t\t    i = ECDH_compute_key(p, (field_size+7)/8, clnt_ecpoint, srvr_ecdh, NULL);\n                if (i <= 0)\n                        {\n                        SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,\n\t\t\t    ERR_R_ECDH_LIB);\n                        goto err;\n                        }\n\t\tEVP_PKEY_free(clnt_pub_pkey);\n\t\tEC_POINT_free(clnt_ecpoint);\n\t\tif (srvr_ecdh != NULL)\n\t\t\t{\n\t\t\tsrvr_ecdh->priv_key = NULL;\n\t\t\tsrvr_ecdh->group = NULL;\n\t\t\tEC_KEY_free(srvr_ecdh);\n\t\t\t}\n\t\tBN_CTX_free(bn_ctx);\n                s->session->master_key_length = s->method->ssl3_enc-> \\\n\t\t    generate_master_secret(s, s->session->master_key, p, i);\n                OPENSSL_cleanse(p, i);\n                return (ret);\n\t\t}\n\telse\n#endif\n\t\t{\n\t\tal=SSL_AD_HANDSHAKE_FAILURE;\n\t\tSSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,\n\t\t\t\tSSL_R_UNKNOWN_CIPHER_TYPE);\n\t\tgoto f_err;\n\t\t}\n\treturn(1);\nf_err:\n\tssl3_send_alert(s,SSL3_AL_FATAL,al);\n#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_ECDH)\nerr:\n#endif\n#ifndef OPENSSL_NO_ECDH\n\tEVP_PKEY_free(clnt_pub_pkey);\n\tEC_POINT_free(clnt_ecpoint);\n\tif (srvr_ecdh != NULL)\n\t\t{\n\t\tsrvr_ecdh->priv_key = NULL;\n\t\tsrvr_ecdh->group = NULL;\n\t\tEC_KEY_free(srvr_ecdh);\n\t\t}\n\tBN_CTX_free(bn_ctx);\n#endif\n\treturn(-1);\n\t}', 'void ERR_put_error(int lib, int func, int reason, const char *file,\n\t     int line)\n\t{\n\tERR_STATE *es;\n#ifdef _OSD_POSIX\n\tif (strncmp(file,"*POSIX(", sizeof("*POSIX(")-1) == 0) {\n\t\tchar *end;\n\t\tfile += sizeof("*POSIX(")-1;\n\t\tend = &file[strlen(file)-1];\n\t\tif (*end == \')\')\n\t\t\t*end = \'\\0\';\n\t\tif ((end = strrchr(file, \'/\')) != NULL)\n\t\t\tfile = &end[1];\n\t}\n#endif\n\tes=ERR_get_state();\n\tes->top=(es->top+1)%ERR_NUM_ERRORS;\n\tif (es->top == es->bottom)\n\t\tes->bottom=(es->bottom+1)%ERR_NUM_ERRORS;\n\tes->err_flags[es->top]=0;\n\tes->err_buffer[es->top]=ERR_PACK(lib,func,reason);\n\tes->err_file[es->top]=file;\n\tes->err_line[es->top]=line;\n\terr_clear_data(es,es->top);\n\t}']