SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_LIB_RSA);
SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_LIB_RSA);
int dtls1_send_server_key_exchange(SSL *s)	{#ifndef OPENSSL_NO_RSA	unsigned char *q;	int j,num;	RSA *rsa;	unsigned char md_buf[MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH];	unsigned int u;#endif#ifndef OPENSSL_NO_DH	DH *dh=NULL,*dhp;#endif	EVP_PKEY *pkey;	unsigned char *p,*d;	int al,i;	unsigned long type;	int n;	CERT *cert;	BIGNUM *r[4];	int nr[4],kn;	BUF_MEM *buf;	EVP_MD_CTX md_ctx;	EVP_MD_CTX_init(&md_ctx);	if (s->state == SSL3_ST_SW_KEY_EXCH_A)		{		type=s->s3->tmp.new_cipher->algorithms & SSL_MKEY_MASK;		cert=s->cert;		buf=s->init_buf;		r[0]=r[1]=r[2]=r[3]=NULL;		n=0;#ifndef OPENSSL_NO_RSA		if (type & SSL_kRSA)			{			rsa=cert->rsa_tmp;			if ((rsa == NULL) && (s->cert->rsa_tmp_cb != NULL))				{				rsa=s->cert->rsa_tmp_cb(s,				      SSL_C_IS_EXPORT(s->s3->tmp.new_cipher),				      SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher));				if(rsa == NULL)				{					al=SSL_AD_HANDSHAKE_FAILURE;					SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_ERROR_GENERATING_TMP_RSA_KEY);					goto f_err;				}				RSA_up_ref(rsa);				cert->rsa_tmp=rsa;				}			if (rsa == NULL)				{				al=SSL_AD_HANDSHAKE_FAILURE;				SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_MISSING_TMP_RSA_KEY);				goto f_err;				}			r[0]=rsa->n;			r[1]=rsa->e;			s->s3->tmp.use_rsa_tmp=1;			}		else#endif#ifndef OPENSSL_NO_DH			if (type & SSL_kEDH)			{			dhp=cert->dh_tmp;			if ((dhp == NULL) && (s->cert->dh_tmp_cb != NULL))				dhp=s->cert->dh_tmp_cb(s,				      SSL_C_IS_EXPORT(s->s3->tmp.new_cipher),				      SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher));			if (dhp == NULL)				{				al=SSL_AD_HANDSHAKE_FAILURE;				SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_MISSING_TMP_DH_KEY);				goto f_err;				}			if (s->s3->tmp.dh != NULL)				{				DH_free(dh);				SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);				goto err;				}			if ((dh=DHparams_dup(dhp)) == NULL)				{				SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_DH_LIB);				goto err;				}			s->s3->tmp.dh=dh;			if ((dhp->pub_key == NULL ||			     dhp->priv_key == NULL ||			     (s->options & SSL_OP_SINGLE_DH_USE)))				{				if(!DH_generate_key(dh))				    {				    SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,					   ERR_R_DH_LIB);				    goto err;				    }				}			else				{				dh->pub_key=BN_dup(dhp->pub_key);				dh->priv_key=BN_dup(dhp->priv_key);				if ((dh->pub_key == NULL) ||					(dh->priv_key == NULL))					{					SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_DH_LIB);					goto err;					}				}			r[0]=dh->p;			r[1]=dh->g;			r[2]=dh->pub_key;			}		else #endif			{			al=SSL_AD_HANDSHAKE_FAILURE;			SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE);			goto f_err;			}		for (i=0; r[i] != NULL; i++)			{			nr[i]=BN_num_bytes(r[i]);			n+=2+nr[i];			}		if (!(s->s3->tmp.new_cipher->algorithms & SSL_aNULL))			{			if ((pkey=ssl_get_sign_pkey(s,s->s3->tmp.new_cipher))				== NULL)				{				al=SSL_AD_DECODE_ERROR;				goto f_err;				}			kn=EVP_PKEY_size(pkey);			}		else			{			pkey=NULL;			kn=0;			}		if (!BUF_MEM_grow_clean(buf,n+DTLS1_HM_HEADER_LENGTH+kn))			{			SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_LIB_BUF);			goto err;			}		d=(unsigned char *)s->init_buf->data;		p= &(d[DTLS1_HM_HEADER_LENGTH]);		for (i=0; r[i] != NULL; i++)			{			s2n(nr[i],p);			BN_bn2bin(r[i],p);			p+=nr[i];			}		/* not anonymous */		if (pkey != NULL)			{			/* n is the length of the params, they start at			 * &(d[DTLS1_HM_HEADER_LENGTH]) and p points to the space			 * at the end. */#ifndef OPENSSL_NO_RSA			if (pkey->type == EVP_PKEY_RSA)				{				q=md_buf;				j=0;				for (num=2; num > 0; num--)					{					EVP_DigestInit_ex(&md_ctx,(num == 2)						?s->ctx->md5:s->ctx->sha1, NULL);					EVP_DigestUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE);					EVP_DigestUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE);					EVP_DigestUpdate(&md_ctx,&(d[DTLS1_HM_HEADER_LENGTH]),n);					EVP_DigestFinal_ex(&md_ctx,q,						(unsigned int *)&i);					q+=i;					j+=i;					}				if (RSA_sign(NID_md5_sha1, md_buf, j,					&(p[2]), &u, pkey->pkey.rsa) <= 0)					{					SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_LIB_RSA);					goto err;					}				s2n(u,p);				n+=u+2;				}			else#endif#if !defined(OPENSSL_NO_DSA)				if (pkey->type == EVP_PKEY_DSA)				{				/* lets do DSS */				EVP_SignInit_ex(&md_ctx,EVP_dss1(), NULL);				EVP_SignUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE);				EVP_SignUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE);				EVP_SignUpdate(&md_ctx,&(d[DTLS1_HM_HEADER_LENGTH]),n);				if (!EVP_SignFinal(&md_ctx,&(p[2]),					(unsigned int *)&i,pkey))					{					SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_LIB_DSA);					goto err;					}				s2n(i,p);				n+=i+2;				}			else#endif				{				/* Is this error check actually needed? */				al=SSL_AD_HANDSHAKE_FAILURE;				SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_UNKNOWN_PKEY_TYPE);				goto f_err;				}			}		d = dtls1_set_message_header(s, d,			SSL3_MT_SERVER_KEY_EXCHANGE, n, 0, n);		/* we should now have things packed up, so lets send		 * it off */		s->init_num=n+DTLS1_HM_HEADER_LENGTH;		s->init_off=0;		/* buffer the message to handle re-xmits */		dtls1_buffer_message(s, 0);		}	s->state = SSL3_ST_SW_KEY_EXCH_B;	EVP_MD_CTX_cleanup(&md_ctx);	return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));f_err:	ssl3_send_alert(s,SSL3_AL_FATAL,al);err:	EVP_MD_CTX_cleanup(&md_ctx);	return(-1);	}