/* ssl/s2_srvr.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 * 
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 * 
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from 
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 * 
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * 
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */

#ifndef NO_RSA
#include <stdio.h>
#include <openssl/bio.h>
#include <openssl/rand.h>
#include <openssl/objects.h>
#include "ssl_locl.h"
#include <openssl/evp.h>

static SSL_METHOD *ssl2_get_server_method(int ver);
static int get_client_master_key(SSL *s);
static int get_client_hello(SSL *s);
static int server_hello(SSL *s); 
static int get_client_finished(SSL *s);
static int server_verify(SSL *s);
static int server_finish(SSL *s);
static int request_certificate(SSL *s);
static int ssl_rsa_private_decrypt(CERT *c, int len, unsigned char *from,
	unsigned char *to,int padding);
#define BREAK	break

static SSL_METHOD *ssl2_get_server_method(int ver)
	{
	if (ver == SSL2_VERSION)
		return(SSLv2_server_method());
	else
		return(NULL);
	}

SSL_METHOD *SSLv2_server_method(void)
	{
	static int init=1;
	static SSL_METHOD SSLv2_server_data;

	if (init)
		{
		memcpy((char *)&SSLv2_server_data,(char *)sslv2_base_method(),
			sizeof(SSL_METHOD));
		SSLv2_server_data.ssl_accept=ssl2_accept;
		SSLv2_server_data.get_ssl_method=ssl2_get_server_method;
		init=0;
		}
	return(&SSLv2_server_data);
	}

int ssl2_accept(SSL *s)
	{
	unsigned long l=time(NULL);
	BUF_MEM *buf=NULL;
	int ret= -1;
	long num1;
	void (*cb)()=NULL;
	int new_state,state;

	RAND_seed(&l,sizeof(l));
	ERR_clear_error();
	clear_sys_error();

	if (s->info_callback != NULL)
		cb=s->info_callback;
	else if (s->ctx->info_callback != NULL)
		cb=s->ctx->info_callback;

	/* init things to blank */
	if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s);
	s->in_handshake++;

	if (s->cert == NULL)
		{
		SSLerr(SSL_F_SSL2_ACCEPT,SSL_R_NO_CERTIFICATE_SET);
		return(-1);
		}

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

		switch (s->state)
			{
		case SSL_ST_BEFORE:
		case SSL_ST_ACCEPT:
		case SSL_ST_BEFORE|SSL_ST_ACCEPT:
		case SSL_ST_OK|SSL_ST_ACCEPT:

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

			s->version=SSL2_VERSION;
			s->type=SSL_ST_ACCEPT;

			buf=s->init_buf;
			if ((buf == NULL) && ((buf=BUF_MEM_new()) == NULL))
				{ ret= -1; goto end; }
			if (!BUF_MEM_grow(buf,(int)
				SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER))
				{ ret= -1; goto end; }
			s->init_buf=buf;
			s->init_num=0;
			s->ctx->stats.sess_accept++;
			s->handshake_func=ssl2_accept;
			s->state=SSL2_ST_GET_CLIENT_HELLO_A;
			BREAK;

		case SSL2_ST_GET_CLIENT_HELLO_A:
		case SSL2_ST_GET_CLIENT_HELLO_B:
		case SSL2_ST_GET_CLIENT_HELLO_C:
			s->shutdown=0;
			ret=get_client_hello(s);
			if (ret <= 0) goto end;
			s->init_num=0;
			s->state=SSL2_ST_SEND_SERVER_HELLO_A;
			BREAK;

		case SSL2_ST_SEND_SERVER_HELLO_A:
		case SSL2_ST_SEND_SERVER_HELLO_B:
			ret=server_hello(s);
			if (ret <= 0) goto end;
			s->init_num=0;
			if (!s->hit)
				{
				s->state=SSL2_ST_GET_CLIENT_MASTER_KEY_A;
				BREAK;
				}
			else
				{
				s->state=SSL2_ST_SERVER_START_ENCRYPTION;
				BREAK;
				}
		case SSL2_ST_GET_CLIENT_MASTER_KEY_A:
		case SSL2_ST_GET_CLIENT_MASTER_KEY_B:
			ret=get_client_master_key(s);
			if (ret <= 0) goto end;
			s->init_num=0;
			s->state=SSL2_ST_SERVER_START_ENCRYPTION;
			BREAK;

		case SSL2_ST_SERVER_START_ENCRYPTION:
			/* Ok we how have sent all the stuff needed to
			 * start encrypting, the next packet back will
			 * be encrypted. */
			if (!ssl2_enc_init(s,0))
				{ ret= -1; goto end; }
			s->s2->clear_text=0;
			s->state=SSL2_ST_SEND_SERVER_VERIFY_A;
			BREAK;

		case SSL2_ST_SEND_SERVER_VERIFY_A:
		case SSL2_ST_SEND_SERVER_VERIFY_B:
			ret=server_verify(s);
			if (ret <= 0) goto end;
			s->init_num=0;
			if (s->hit)
				{
				/* If we are in here, we have been
				 * buffering the output, so we need to
				 * flush it and remove buffering from
				 * future traffic */
				s->state=SSL2_ST_SEND_SERVER_VERIFY_C;
				BREAK;
				}
			else
				{
				s->state=SSL2_ST_GET_CLIENT_FINISHED_A;
				break;
				}

 		case SSL2_ST_SEND_SERVER_VERIFY_C:
 			/* get the number of bytes to write */
 			num1=BIO_ctrl(s->wbio,BIO_CTRL_INFO,0,NULL);
 			if (num1 != 0)
 				{
				s->rwstate=SSL_WRITING;
 				num1=BIO_flush(s->wbio);
 				if (num1 <= 0) { ret= -1; goto end; }
				s->rwstate=SSL_NOTHING;
				}

 			/* flushed and now remove buffering */
 			s->wbio=BIO_pop(s->wbio);

 			s->state=SSL2_ST_GET_CLIENT_FINISHED_A;
  			BREAK;

		case SSL2_ST_GET_CLIENT_FINISHED_A:
		case SSL2_ST_GET_CLIENT_FINISHED_B:
			ret=get_client_finished(s);
			if (ret <= 0)
				goto end;
			s->init_num=0;
			s->state=SSL2_ST_SEND_REQUEST_CERTIFICATE_A;
			BREAK;

		case SSL2_ST_SEND_REQUEST_CERTIFICATE_A:
		case SSL2_ST_SEND_REQUEST_CERTIFICATE_B:
		case SSL2_ST_SEND_REQUEST_CERTIFICATE_C:
		case SSL2_ST_SEND_REQUEST_CERTIFICATE_D:
			/* don't do a 'request certificate' if we
			 * don't want to, or we already have one, and
			 * we only want to do it once. */
			if (!(s->verify_mode & SSL_VERIFY_PEER) ||
				((s->session->peer != NULL) &&
				(s->verify_mode & SSL_VERIFY_CLIENT_ONCE)))
				{
				s->state=SSL2_ST_SEND_SERVER_FINISHED_A;
				break;
				}
			else
				{
				ret=request_certificate(s);
				if (ret <= 0) goto end;
				s->init_num=0;
				s->state=SSL2_ST_SEND_SERVER_FINISHED_A;
				}
			BREAK;

		case SSL2_ST_SEND_SERVER_FINISHED_A:
		case SSL2_ST_SEND_SERVER_FINISHED_B:
			ret=server_finish(s);
			if (ret <= 0) goto end;
			s->init_num=0;
			s->state=SSL_ST_OK;
			break;

		case SSL_ST_OK:
			BUF_MEM_free(s->init_buf);
			ssl_free_wbio_buffer(s);
			s->init_buf=NULL;
			s->init_num=0;
		/*	ERR_clear_error();*/

			ssl_update_cache(s,SSL_SESS_CACHE_SERVER);

			s->ctx->stats.sess_accept_good++;
			/* s->server=1; */
			ret=1;

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

			goto end;
			/* BREAK; */

		default:
			SSLerr(SSL_F_SSL2_ACCEPT,SSL_R_UNKNOWN_STATE);
			ret= -1;
			goto end;
			/* BREAK; */
			}
		
		if ((cb != NULL) && (s->state != state))
			{
			new_state=s->state;
			s->state=state;
			cb(s,SSL_CB_ACCEPT_LOOP,1);
			s->state=new_state;
			}
		}
end:
	s->in_handshake--;
	if (cb != NULL)
		cb(s,SSL_CB_ACCEPT_EXIT,ret);
	return(ret);
	}

static int get_client_master_key(SSL *s)
	{
	int is_export,i,n,keya,ek;
	unsigned char *p;
	SSL_CIPHER *cp;
	const EVP_CIPHER *c;
	const EVP_MD *md;

	p=(unsigned char *)s->init_buf->data;
	if (s->state == SSL2_ST_GET_CLIENT_MASTER_KEY_A)
		{
		i=ssl2_read(s,(char *)&(p[s->init_num]),10-s->init_num);

		if (i < (10-s->init_num))
			return(ssl2_part_read(s,SSL_F_GET_CLIENT_MASTER_KEY,i));
		if (*(p++) != SSL2_MT_CLIENT_MASTER_KEY)
			{
			if (p[-1] != SSL2_MT_ERROR)
				{
				ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
				SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_READ_WRONG_PACKET_TYPE);
				}
			else
				SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,
					SSL_R_PEER_ERROR);
			return(-1);
			}

		cp=ssl2_get_cipher_by_char(p);
		if (cp == NULL)
			{
			ssl2_return_error(s,SSL2_PE_NO_CIPHER);
			SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,
				SSL_R_NO_CIPHER_MATCH);
			return(-1);
			}
		s->session->cipher= cp;

		p+=3;
		n2s(p,i); s->s2->tmp.clear=i;
		n2s(p,i); s->s2->tmp.enc=i;
		n2s(p,i); s->session->key_arg_length=i;
		s->state=SSL2_ST_GET_CLIENT_MASTER_KEY_B;
		s->init_num=0;
		}

	/* SSL2_ST_GET_CLIENT_MASTER_KEY_B */
	p=(unsigned char *)s->init_buf->data;
	keya=s->session->key_arg_length;
	n=s->s2->tmp.clear+s->s2->tmp.enc+keya - s->init_num;
	i=ssl2_read(s,(char *)&(p[s->init_num]),n);
	if (i != n) return(ssl2_part_read(s,SSL_F_GET_CLIENT_MASTER_KEY,i));

	memcpy(s->session->key_arg,&(p[s->s2->tmp.clear+s->s2->tmp.enc]),
		(unsigned int)keya);

	if (s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL)
		{
		ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
		SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_NO_PRIVATEKEY);
		return(-1);
		}
	i=ssl_rsa_private_decrypt(s->cert,s->s2->tmp.enc,
		&(p[s->s2->tmp.clear]),&(p[s->s2->tmp.clear]),
		(s->s2->ssl2_rollback)?RSA_SSLV23_PADDING:RSA_PKCS1_PADDING);

	is_export=SSL_C_IS_EXPORT(s->session->cipher);
	
	if (!ssl_cipher_get_evp(s->session,&c,&md,NULL))
		{
		ssl2_return_error(s,SSL2_PE_NO_CIPHER);
		SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS);
		return(0);
		}

	if (s->session->cipher->algorithm2 & SSL2_CF_8_BYTE_ENC)
		{
		is_export=1;
		ek=8;
		}
	else
		ek=5;

	/* bad decrypt */
#if 1
	/* If a bad decrypt, continue with protocol but with a
	 * dud master secret */
	if ((i < 0) ||
		((!is_export && (i != EVP_CIPHER_key_length(c)))
		|| (is_export && ((i != ek) || (s->s2->tmp.clear+i !=
			EVP_CIPHER_key_length(c))))))
		{
		if (is_export)
			i=ek;
		else
			i=EVP_CIPHER_key_length(c);
		RAND_bytes(p,i);
		}
#else
	if (i < 0)
		{
		error=1;
		SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_BAD_RSA_DECRYPT);
		}
	/* incorrect number of key bytes for non export cipher */
	else if ((!is_export && (i != EVP_CIPHER_key_length(c)))
		|| (is_export && ((i != ek) || (s->s2->tmp.clear+i !=
			EVP_CIPHER_key_length(c)))))
		{
		error=1;
		SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_WRONG_NUMBER_OF_KEY_BITS);
		}
	if (error)
		{
		ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
		return(-1);
		}
#endif

	if (is_export) i+=s->s2->tmp.clear;
	s->session->master_key_length=i;
	memcpy(s->session->master_key,p,(unsigned int)i);
	return(1);
	}

static int get_client_hello(SSL *s)
	{
	int i,n;
	unsigned char *p;
	STACK_OF(SSL_CIPHER) *cs; /* a stack of SSL_CIPHERS */
	STACK_OF(SSL_CIPHER) *cl; /* the ones we want to use */
	int z;

	/* This is a bit of a hack to check for the correct packet
	 * type the first time round. */
	if (s->state == SSL2_ST_GET_CLIENT_HELLO_A)
		{
		s->first_packet=1;
		s->state=SSL2_ST_GET_CLIENT_HELLO_B;
		}

	p=(unsigned char *)s->init_buf->data;
	if (s->state == SSL2_ST_GET_CLIENT_HELLO_B)
		{
		i=ssl2_read(s,(char *)&(p[s->init_num]),9-s->init_num);
		if (i < (9-s->init_num)) 
			return(ssl2_part_read(s,SSL_F_GET_CLIENT_HELLO,i));
	
		if (*(p++) != SSL2_MT_CLIENT_HELLO)
			{
			if (p[-1] != SSL2_MT_ERROR)
				{
				ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
				SSLerr(SSL_F_GET_CLIENT_HELLO,SSL_R_READ_WRONG_PACKET_TYPE);
				}
			else
				SSLerr(SSL_F_GET_CLIENT_HELLO,SSL_R_PEER_ERROR);
			return(-1);
			}
		n2s(p,i);
		if (i < s->version) s->version=i;
		n2s(p,i); s->s2->tmp.cipher_spec_length=i;
		n2s(p,i); s->s2->tmp.session_id_length=i;
		n2s(p,i); s->s2->challenge_length=i;
		if (	(i < SSL2_MIN_CHALLENGE_LENGTH) ||
			(i > SSL2_MAX_CHALLENGE_LENGTH))
			{
			SSLerr(SSL_F_GET_CLIENT_HELLO,SSL_R_INVALID_CHALLENGE_LENGTH);
			return(-1);
			}
		s->state=SSL2_ST_GET_CLIENT_HELLO_C;
		s->init_num=0;
		}

	/* SSL2_ST_GET_CLIENT_HELLO_C */
	p=(unsigned char *)s->init_buf->data;
	n=s->s2->tmp.cipher_spec_length+s->s2->challenge_length+
		s->s2->tmp.session_id_length-s->init_num;
	i=ssl2_read(s,(char *)&(p[s->init_num]),n);
	if (i != n) return(ssl2_part_read(s,SSL_F_GET_CLIENT_HELLO,i));

	/* get session-id before cipher stuff so we can get out session
	 * structure if it is cached */
	/* session-id */
	if ((s->s2->tmp.session_id_length != 0) && 
		(s->s2->tmp.session_id_length != SSL2_SSL_SESSION_ID_LENGTH))
		{
		ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
		SSLerr(SSL_F_GET_CLIENT_HELLO,SSL_R_BAD_SSL_SESSION_ID_LENGTH);
		return(-1);
		}

	if (s->s2->tmp.session_id_length == 0)
		{
		if (!ssl_get_new_session(s,1))
			{
			ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
			return(-1);
			}
		}
	else
		{
		i=ssl_get_prev_session(s,&(p[s->s2->tmp.cipher_spec_length]),
			s->s2->tmp.session_id_length);
		if (i == 1)
			{ /* previous session */
			s->hit=1;
			}
		else if (i == -1)
			{
			ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
			return(-1);
			}
		else
			{
			if (s->cert == NULL)
				{
				ssl2_return_error(s,SSL2_PE_NO_CERTIFICATE);
				SSLerr(SSL_F_GET_CLIENT_HELLO,SSL_R_NO_CERTIFICATE_SET);
				return(-1);
				}

			if (!ssl_get_new_session(s,1))
				{
				ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
				return(-1);
				}
			}
		}

	if (!s->hit)
		{
		cs=ssl_bytes_to_cipher_list(s,p,s->s2->tmp.cipher_spec_length,
			&s->session->ciphers);
		if (cs == NULL) goto mem_err;

		cl=ssl_get_ciphers_by_id(s);

		for (z=0; z<sk_SSL_CIPHER_num(cs); z++)
			{
			if (sk_SSL_CIPHER_find(cl,sk_SSL_CIPHER_value(cs,z)) < 0)
				{
				sk_SSL_CIPHER_delete(cs,z);
				z--;
				}
			}

		/* s->session->ciphers should now have a list of
		 * ciphers that are on both the client and server.
		 * This list is ordered by the order the client sent
		 * the ciphers.
		 */
		}
	p+=s->s2->tmp.cipher_spec_length;
	/* done cipher selection */

	/* session id extracted already */
	p+=s->s2->tmp.session_id_length;

	/* challenge */
	memcpy(s->s2->challenge,p,(unsigned int)s->s2->challenge_length);
	return(1);
mem_err:
	SSLerr(SSL_F_GET_CLIENT_HELLO,ERR_R_MALLOC_FAILURE);
	return(0);
	}

static int server_hello(SSL *s)
	{
	unsigned char *p,*d;
	int n,hit;
	STACK_OF(SSL_CIPHER) *sk;

	p=(unsigned char *)s->init_buf->data;
	if (s->state == SSL2_ST_SEND_SERVER_HELLO_A)
		{
		d=p+11;
		*(p++)=SSL2_MT_SERVER_HELLO;		/* type */
		hit=s->hit;
		*(p++)=(unsigned char)hit;
#if 1
		if (!hit)
			{
			if (s->session->sess_cert != NULL)
				/* This can't really happen because get_client_hello
				 * has called ssl_get_new_session, which does not set
				 * sess_cert. */
				ssl_sess_cert_free(s->session->sess_cert);
			s->session->sess_cert = ssl_sess_cert_new();
			if (s->session->sess_cert == NULL)
				{
				SSLerr(SSL_F_SERVER_HELLO, ERR_R_MALLOC_FAILURE);
				return(-1);
				}
			}
		/* If 'hit' is set, then s->sess_cert may be non-NULL or NULL,
		 * depending on whether it survived in the internal cache
		 * or was retrieved from an external cache.
		 * If it is NULL, we cannot put any useful data in it anyway,
		 * so we don't touch it.
		 */

#else /* That's what used to be done when cert_st and sess_cert_st were
	   * the same. */
		if (!hit)
			{			/* else add cert to session */
			CRYPTO_add(&s->cert->references,1,CRYPTO_LOCK_SSL_CERT);
			if (s->session->sess_cert != NULL)
				ssl_cert_free(s->session->sess_cert);
			s->session->sess_cert=s->cert;		
			}
		else	/* We have a session id-cache hit, if the
			 * session-id has no certificate listed against
			 * the 'cert' structure, grab the 'old' one
			 * listed against the SSL connection */
			{
			if (s->session->sess_cert == NULL)
				{
				CRYPTO_add(&s->cert->references,1,
					CRYPTO_LOCK_SSL_CERT);
				s->session->sess_cert=s->cert;
				}
			}
#endif

		if (s->cert == NULL)
			{
			ssl2_return_error(s,SSL2_PE_NO_CERTIFICATE);
			SSLerr(SSL_F_SERVER_HELLO,SSL_R_NO_CERTIFICATE_SPECIFIED);
			return(-1);
			}

		if (hit)
			{
			*(p++)=0;		/* no certificate type */
			s2n(s->version,p);	/* version */
			s2n(0,p);		/* cert len */
			s2n(0,p);		/* ciphers len */
			}
		else
			{
			/* EAY EAY */
			/* put certificate type */
			*(p++)=SSL2_CT_X509_CERTIFICATE;
			s2n(s->version,p);	/* version */
			n=i2d_X509(s->cert->pkeys[SSL_PKEY_RSA_ENC].x509,NULL);
			s2n(n,p);		/* certificate length */
			i2d_X509(s->cert->pkeys[SSL_PKEY_RSA_ENC].x509,&d);
			n=0;
			
			/* lets send out the ciphers we like in the
			 * prefered order */
			sk= s->session->ciphers;
			n=ssl_cipher_list_to_bytes(s,s->session->ciphers,d);
			d+=n;
			s2n(n,p);		/* add cipher length */
			}

		/* make and send conn_id */
		s2n(SSL2_CONNECTION_ID_LENGTH,p);	/* add conn_id length */
		s->s2->conn_id_length=SSL2_CONNECTION_ID_LENGTH;
		RAND_bytes(s->s2->conn_id,(int)s->s2->conn_id_length);
		memcpy(d,s->s2->conn_id,SSL2_CONNECTION_ID_LENGTH);
		d+=SSL2_CONNECTION_ID_LENGTH;

		s->state=SSL2_ST_SEND_SERVER_HELLO_B;
		s->init_num=d-(unsigned char *)s->init_buf->data;
		s->init_off=0;
		}
	/* SSL2_ST_SEND_SERVER_HELLO_B */
 	/* If we are using TCP/IP, the performace is bad if we do 2
 	 * writes without a read between them.  This occurs when
 	 * Session-id reuse is used, so I will put in a buffering module
 	 */
 	if (s->hit)
 		{
		if (!ssl_init_wbio_buffer(s,1)) return(-1);
 		}
 
	return(ssl2_do_write(s));
	}

static int get_client_finished(SSL *s)
	{
	unsigned char *p;
	int i;

	p=(unsigned char *)s->init_buf->data;
	if (s->state == SSL2_ST_GET_CLIENT_FINISHED_A)
		{
		i=ssl2_read(s,(char *)&(p[s->init_num]),1-s->init_num);
		if (i < 1-s->init_num)
			return(ssl2_part_read(s,SSL_F_GET_CLIENT_FINISHED,i));

		if (*p != SSL2_MT_CLIENT_FINISHED)
			{
			if (*p != SSL2_MT_ERROR)
				{
				ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
				SSLerr(SSL_F_GET_CLIENT_FINISHED,SSL_R_READ_WRONG_PACKET_TYPE);
				}
			else
				SSLerr(SSL_F_GET_CLIENT_FINISHED,SSL_R_PEER_ERROR);
			return(-1);
			}
		s->init_num=0;
		s->state=SSL2_ST_GET_CLIENT_FINISHED_B;
		}

	/* SSL2_ST_GET_CLIENT_FINISHED_B */
	i=ssl2_read(s,(char *)&(p[s->init_num]),s->s2->conn_id_length-s->init_num);
	if (i < (int)s->s2->conn_id_length-s->init_num)
		{
		return(ssl2_part_read(s,SSL_F_GET_CLIENT_FINISHED,i));
		}
	if (memcmp(p,s->s2->conn_id,(unsigned int)s->s2->conn_id_length) != 0)
		{
		ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
		SSLerr(SSL_F_GET_CLIENT_FINISHED,SSL_R_CONNECTION_ID_IS_DIFFERENT);
		return(-1);
		}
	return(1);
	}

static int server_verify(SSL *s)
	{
	unsigned char *p;

	if (s->state == SSL2_ST_SEND_SERVER_VERIFY_A)
		{
		p=(unsigned char *)s->init_buf->data;
		*(p++)=SSL2_MT_SERVER_VERIFY;
		memcpy(p,s->s2->challenge,(unsigned int)s->s2->challenge_length);
		/* p+=s->s2->challenge_length; */

		s->state=SSL2_ST_SEND_SERVER_VERIFY_B;
		s->init_num=s->s2->challenge_length+1;
		s->init_off=0;
		}
	return(ssl2_do_write(s));
	}

static int server_finish(SSL *s)
	{
	unsigned char *p;

	if (s->state == SSL2_ST_SEND_SERVER_FINISHED_A)
		{
		p=(unsigned char *)s->init_buf->data;
		*(p++)=SSL2_MT_SERVER_FINISHED;

		memcpy(p,s->session->session_id,
			(unsigned int)s->session->session_id_length);
		/* p+=s->session->session_id_length; */

		s->state=SSL2_ST_SEND_SERVER_FINISHED_B;
		s->init_num=s->session->session_id_length+1;
		s->init_off=0;
		}

	/* SSL2_ST_SEND_SERVER_FINISHED_B */
	return(ssl2_do_write(s));
	}

/* send the request and check the response */
static int request_certificate(SSL *s)
	{
	unsigned char *p,*p2,*buf2;
	unsigned char *ccd;
	int i,j,ctype,ret= -1;
	X509 *x509=NULL;
	STACK_OF(X509) *sk=NULL;

	ccd=s->s2->tmp.ccl;
	if (s->state == SSL2_ST_SEND_REQUEST_CERTIFICATE_A)
		{
		p=(unsigned char *)s->init_buf->data;
		*(p++)=SSL2_MT_REQUEST_CERTIFICATE;
		*(p++)=SSL2_AT_MD5_WITH_RSA_ENCRYPTION;
		RAND_bytes(ccd,SSL2_MIN_CERT_CHALLENGE_LENGTH);
		memcpy(p,ccd,SSL2_MIN_CERT_CHALLENGE_LENGTH);

		s->state=SSL2_ST_SEND_REQUEST_CERTIFICATE_B;
		s->init_num=SSL2_MIN_CERT_CHALLENGE_LENGTH+2;
		s->init_off=0;
		}

	if (s->state == SSL2_ST_SEND_REQUEST_CERTIFICATE_B)
		{
		i=ssl2_do_write(s);
		if (i <= 0)
			{
			ret=i;
			goto end;
			}

		s->init_num=0;
		s->state=SSL2_ST_SEND_REQUEST_CERTIFICATE_C;
		}

	if (s->state == SSL2_ST_SEND_REQUEST_CERTIFICATE_C)
		{
		p=(unsigned char *)s->init_buf->data;
		i=ssl2_read(s,(char *)&(p[s->init_num]),6-s->init_num);
		if (i < 3)
			{
			ret=ssl2_part_read(s,SSL_F_REQUEST_CERTIFICATE,i);
			goto end;
			}

		if ((*p == SSL2_MT_ERROR) && (i >= 3))
			{
			n2s(p,i);
			if (s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)
				{
				ssl2_return_error(s,SSL2_PE_BAD_CERTIFICATE);
				SSLerr(SSL_F_REQUEST_CERTIFICATE,SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE);
				goto end;
				}
			ret=1;
			goto end;
			}
		if ((*(p++) != SSL2_MT_CLIENT_CERTIFICATE) || (i < 6))
			{
			ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
			SSLerr(SSL_F_REQUEST_CERTIFICATE,SSL_R_SHORT_READ);
			goto end;
			}
		/* ok we have a response */
		/* certificate type, there is only one right now. */
		ctype= *(p++);
		if (ctype != SSL2_AT_MD5_WITH_RSA_ENCRYPTION)
			{
			ssl2_return_error(s,SSL2_PE_UNSUPPORTED_CERTIFICATE_TYPE);
			SSLerr(SSL_F_REQUEST_CERTIFICATE,SSL_R_BAD_RESPONSE_ARGUMENT);
			goto end;
			}
		n2s(p,i); s->s2->tmp.clen=i;
		n2s(p,i); s->s2->tmp.rlen=i;
		s->state=SSL2_ST_SEND_REQUEST_CERTIFICATE_D;
		s->init_num=0;
		}

	/* SSL2_ST_SEND_REQUEST_CERTIFICATE_D */
	p=(unsigned char *)s->init_buf->data;
	j=s->s2->tmp.clen+s->s2->tmp.rlen-s->init_num;
	i=ssl2_read(s,(char *)&(p[s->init_num]),j);
	if (i < j) 
		{
		ret=ssl2_part_read(s,SSL_F_REQUEST_CERTIFICATE,i);
		goto end;
		}

	x509=(X509 *)d2i_X509(NULL,&p,(long)s->s2->tmp.clen);
	if (x509 == NULL)
		{
		SSLerr(SSL_F_REQUEST_CERTIFICATE,ERR_R_X509_LIB);
		goto msg_end;
		}

	if (((sk=sk_X509_new_null()) == NULL) || (!sk_X509_push(sk,x509)))
		{
		SSLerr(SSL_F_REQUEST_CERTIFICATE,ERR_R_MALLOC_FAILURE);
		goto msg_end;
		}

	i=ssl_verify_cert_chain(s,sk);

	if (i)	/* we like the packet, now check the chksum */
		{
		EVP_MD_CTX ctx;
		EVP_PKEY *pkey=NULL;

		EVP_VerifyInit(&ctx,s->ctx->rsa_md5);
		EVP_VerifyUpdate(&ctx,s->s2->key_material,
			(unsigned int)s->s2->key_material_length);
		EVP_VerifyUpdate(&ctx,ccd,SSL2_MIN_CERT_CHALLENGE_LENGTH);

		i=i2d_X509(s->cert->pkeys[SSL_PKEY_RSA_ENC].x509,NULL);
		buf2=(unsigned char *)Malloc((unsigned int)i);
		if (buf2 == NULL)
			{
			SSLerr(SSL_F_REQUEST_CERTIFICATE,ERR_R_MALLOC_FAILURE);
			goto msg_end;
			}
		p2=buf2;
		i=i2d_X509(s->cert->pkeys[SSL_PKEY_RSA_ENC].x509,&p2);
		EVP_VerifyUpdate(&ctx,buf2,(unsigned int)i);
		Free(buf2);

		pkey=X509_get_pubkey(x509);
		if (pkey == NULL) goto end;
		i=EVP_VerifyFinal(&ctx,p,s->s2->tmp.rlen,pkey);
		EVP_PKEY_free(pkey);
		memset(&ctx,0,sizeof(ctx));

		if (i) 
			{
			if (s->session->peer != NULL)
				X509_free(s->session->peer);
			s->session->peer=x509;
			CRYPTO_add(&x509->references,1,CRYPTO_LOCK_X509);
			ret=1;
			goto end;
			}
		else
			{
			SSLerr(SSL_F_REQUEST_CERTIFICATE,SSL_R_BAD_CHECKSUM);
			goto msg_end;
			}
		}
	else
		{
msg_end:
		ssl2_return_error(s,SSL2_PE_BAD_CERTIFICATE);
		}
end:
	sk_X509_free(sk);
	X509_free(x509);
	return(ret);
	}

static int ssl_rsa_private_decrypt(CERT *c, int len, unsigned char *from,
	     unsigned char *to, int padding)
	{
	RSA *rsa;
	int i;

	if ((c == NULL) || (c->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL))
		{
		SSLerr(SSL_F_SSL_RSA_PRIVATE_DECRYPT,SSL_R_NO_PRIVATEKEY);
		return(-1);
		}
	if (c->pkeys[SSL_PKEY_RSA_ENC].privatekey->type != EVP_PKEY_RSA)
		{
		SSLerr(SSL_F_SSL_RSA_PRIVATE_DECRYPT,SSL_R_PUBLIC_KEY_IS_NOT_RSA);
		return(-1);
		}
	rsa=c->pkeys[SSL_PKEY_RSA_ENC].privatekey->pkey.rsa;

	/* we have the public key */
	i=RSA_private_decrypt(len,from,to,rsa,padding);
	if (i < 0)
		SSLerr(SSL_F_SSL_RSA_PRIVATE_DECRYPT,ERR_R_RSA_LIB);
	return(i);
	}
#endif
