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

static SSL_METHOD *ssl2_get_client_method(int ver);
static int get_server_finished(SSL *s);
static int get_server_verify(SSL *s);
static int get_server_hello(SSL *s);
static int client_hello(SSL *s); 
static int client_master_key(SSL *s);
static int client_finished(SSL *s);
static int client_certificate(SSL *s);
static int ssl_rsa_public_encrypt(SESS_CERT *sc, int len, unsigned char *from,
	unsigned char *to,int padding);
#define BREAK	break

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

SSL_METHOD *SSLv2_client_method(void)
	{
	static int init=1;
	static SSL_METHOD SSLv2_client_data;

	if (init)
		{
		CRYPTO_w_lock(CRYPTO_LOCK_SSL_METHOD);

		if (init)
			{
			memcpy((char *)&SSLv2_client_data,(char *)sslv2_base_method(),
				sizeof(SSL_METHOD));
			SSLv2_client_data.ssl_connect=ssl2_connect;
			SSLv2_client_data.get_ssl_method=ssl2_get_client_method;
			init=0;
			}

		CRYPTO_w_unlock(CRYPTO_LOCK_SSL_METHOD);
		}
	return(&SSLv2_client_data);
	}

int ssl2_connect(SSL *s)
	{
	unsigned long l=time(NULL);
	BUF_MEM *buf=NULL;
	int ret= -1;
	void (*cb)(const SSL *ssl,int type,int val)=NULL;
	int new_state,state;

	RAND_add(&l,sizeof(l),0);
	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 */
	s->in_handshake++;
	if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s);

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

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

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

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

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

		case SSL2_ST_SEND_CLIENT_HELLO_A:
		case SSL2_ST_SEND_CLIENT_HELLO_B:
			s->shutdown=0;
			ret=client_hello(s);
			if (ret <= 0) goto end;
			s->init_num=0;
			s->state=SSL2_ST_GET_SERVER_HELLO_A;
			BREAK;
		
		case SSL2_ST_GET_SERVER_HELLO_A:
		case SSL2_ST_GET_SERVER_HELLO_B:
			ret=get_server_hello(s);
			if (ret <= 0) goto end;
			s->init_num=0;
			if (!s->hit) /* new session */
				{
				s->state=SSL2_ST_SEND_CLIENT_MASTER_KEY_A;
				BREAK; 
				}
			else
				{
				s->state=SSL2_ST_CLIENT_START_ENCRYPTION;
				break;
				}
	
		case SSL2_ST_SEND_CLIENT_MASTER_KEY_A:
		case SSL2_ST_SEND_CLIENT_MASTER_KEY_B:
			ret=client_master_key(s);
			if (ret <= 0) goto end;
			s->init_num=0;
			s->state=SSL2_ST_CLIENT_START_ENCRYPTION;
			break;

		case SSL2_ST_CLIENT_START_ENCRYPTION:
			/* Ok, we now have all the stuff needed to
			 * start encrypting, so lets fire it up :-) */
			if (!ssl2_enc_init(s,1))
				{
				ret= -1;
				goto end;
				}
			s->s2->clear_text=0;
			s->state=SSL2_ST_SEND_CLIENT_FINISHED_A;
			break;

		case SSL2_ST_SEND_CLIENT_FINISHED_A:
		case SSL2_ST_SEND_CLIENT_FINISHED_B:
			ret=client_finished(s);
			if (ret <= 0) goto end;
			s->init_num=0;
			s->state=SSL2_ST_GET_SERVER_VERIFY_A;
			break;

		case SSL2_ST_GET_SERVER_VERIFY_A:
		case SSL2_ST_GET_SERVER_VERIFY_B:
			ret=get_server_verify(s);
			if (ret <= 0) goto end;
			s->init_num=0;
			s->state=SSL2_ST_GET_SERVER_FINISHED_A;
			break;

		case SSL2_ST_GET_SERVER_FINISHED_A:
		case SSL2_ST_GET_SERVER_FINISHED_B:
			ret=get_server_finished(s);
			if (ret <= 0) goto end;
			break;

		case SSL2_ST_SEND_CLIENT_CERTIFICATE_A:
		case SSL2_ST_SEND_CLIENT_CERTIFICATE_B:
		case SSL2_ST_SEND_CLIENT_CERTIFICATE_C:
		case SSL2_ST_SEND_CLIENT_CERTIFICATE_D:
		case SSL2_ST_X509_GET_CLIENT_CERTIFICATE:
			ret=client_certificate(s);
			if (ret <= 0) goto end;
			s->init_num=0;
			s->state=SSL2_ST_GET_SERVER_FINISHED_A;
			break;

		case SSL_ST_OK:
			if (s->init_buf != NULL)
				{
				BUF_MEM_free(s->init_buf);
				s->init_buf=NULL;
				}
			s->init_num=0;
		/*	ERR_clear_error();*/

			/* If we want to cache session-ids in the client
			 * and we successfully add the session-id to the
			 * cache, and there is a callback, then pass it out.
			 * 26/11/96 - eay - only add if not a re-used session.
			 */

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

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

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

			goto end;
			/* break; */
		default:
			SSLerr(SSL_F_SSL2_CONNECT,SSL_R_UNKNOWN_STATE);
			return(-1);
			/* break; */
			}

		if ((cb != NULL) && (s->state != state))
			{
			new_state=s->state;
			s->state=state;
			cb(s,SSL_CB_CONNECT_LOOP,1);
			s->state=new_state;
			}
		}
end:
	s->in_handshake--;
	if (buf != NULL)
		BUF_MEM_free(buf);
	if (cb != NULL) 
		cb(s,SSL_CB_CONNECT_EXIT,ret);
	return(ret);
	}

static int get_server_hello(SSL *s)
	{
	unsigned char *buf;
	unsigned char *p;
	int i,j;
	unsigned long len;
	STACK_OF(SSL_CIPHER) *sk=NULL,*cl, *prio, *allow;

	buf=(unsigned char *)s->init_buf->data;
	p=buf;
	if (s->state == SSL2_ST_GET_SERVER_HELLO_A)
		{
		i=ssl2_read(s,(char *)&(buf[s->init_num]),11-s->init_num);
		if (i < (11-s->init_num)) 
			return(ssl2_part_read(s,SSL_F_GET_SERVER_HELLO,i));
		s->init_num = 11;

		if (*(p++) != SSL2_MT_SERVER_HELLO)
			{
			if (p[-1] != SSL2_MT_ERROR)
				{
				ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
				SSLerr(SSL_F_GET_SERVER_HELLO,
					SSL_R_READ_WRONG_PACKET_TYPE);
				}
			else
				SSLerr(SSL_F_GET_SERVER_HELLO,
					SSL_R_PEER_ERROR);
			return(-1);
			}
#ifdef __APPLE_CC__
		/* The Rhapsody 5.5 (a.k.a. MacOS X) compiler bug
		 * workaround. <appro@fy.chalmers.se> */
		s->hit=(i=*(p++))?1:0;
#else
		s->hit=(*(p++))?1:0;
#endif
		s->s2->tmp.cert_type= *(p++);
		n2s(p,i);
		if (i < s->version) s->version=i;
		n2s(p,i); s->s2->tmp.cert_length=i;
		n2s(p,i); s->s2->tmp.csl=i;
		n2s(p,i); s->s2->tmp.conn_id_length=i;
		s->state=SSL2_ST_GET_SERVER_HELLO_B;
		}

	/* SSL2_ST_GET_SERVER_HELLO_B */
	len = 11 + (unsigned long)s->s2->tmp.cert_length + (unsigned long)s->s2->tmp.csl + (unsigned long)s->s2->tmp.conn_id_length;
	if (len > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)
		{
		SSLerr(SSL_F_GET_SERVER_HELLO,SSL_R_MESSAGE_TOO_LONG);
		return -1;
		}
	j = (int)len - s->init_num;
	i = ssl2_read(s,(char *)&(buf[s->init_num]),j);
	if (i != j) return(ssl2_part_read(s,SSL_F_GET_SERVER_HELLO,i));
	if (s->msg_callback)
		s->msg_callback(0, s->version, 0, buf, (size_t)len, s, s->msg_callback_arg); /* SERVER-HELLO */

	/* things are looking good */

	p = buf + 11;
	if (s->hit)
		{
		if (s->s2->tmp.cert_length != 0) 
			{
			SSLerr(SSL_F_GET_SERVER_HELLO,SSL_R_REUSE_CERT_LENGTH_NOT_ZERO);
			return(-1);
			}
		if (s->s2->tmp.cert_type != 0)
			{
			if (!(s->options &
				SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG))
				{
				SSLerr(SSL_F_GET_SERVER_HELLO,SSL_R_REUSE_CERT_TYPE_NOT_ZERO);
				return(-1);
				}
			}
		if (s->s2->tmp.csl != 0)
			{
			SSLerr(SSL_F_GET_SERVER_HELLO,SSL_R_REUSE_CIPHER_LIST_NOT_ZERO);
			return(-1);
			}
		}
	else
		{
#ifdef undef
		/* very bad */
		memset(s->session->session_id,0,
			SSL_MAX_SSL_SESSION_ID_LENGTH_IN_BYTES);
		s->session->session_id_length=0;
		*/
#endif

		/* we need to do this in case we were trying to reuse a 
		 * client session but others are already reusing it.
		 * If this was a new 'blank' session ID, the session-id
		 * length will still be 0 */
		if (s->session->session_id_length > 0)
			{
			if (!ssl_get_new_session(s,0))
				{
				ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
				return(-1);
				}
			}

		if (ssl2_set_certificate(s,s->s2->tmp.cert_type,
			s->s2->tmp.cert_length,p) <= 0)
			{
			ssl2_return_error(s,SSL2_PE_BAD_CERTIFICATE);
			return(-1);
			}
		p+=s->s2->tmp.cert_length;

		if (s->s2->tmp.csl == 0)
			{
			ssl2_return_error(s,SSL2_PE_NO_CIPHER);
			SSLerr(SSL_F_GET_SERVER_HELLO,SSL_R_NO_CIPHER_LIST);
			return(-1);
			}

		/* We have just received a list of ciphers back from the
		 * server.  We need to get the ones that match, then select
		 * the one we want the most :-). */

		/* load the ciphers */
		sk=ssl_bytes_to_cipher_list(s,p,s->s2->tmp.csl,
					    &s->session->ciphers);
		p+=s->s2->tmp.csl;
		if (sk == NULL)
			{
			ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
			SSLerr(SSL_F_GET_SERVER_HELLO,ERR_R_MALLOC_FAILURE);
			return(-1);
			}

		sk_SSL_CIPHER_set_cmp_func(sk,ssl_cipher_ptr_id_cmp);

		/* get the array of ciphers we will accept */
		cl=SSL_get_ciphers(s);
		sk_SSL_CIPHER_set_cmp_func(cl,ssl_cipher_ptr_id_cmp);

		/*
		 * If server preference flag set, choose the first
		 * (highest priority) cipher the server sends, otherwise
		 * client preference has priority.
		 */
		if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE)
		    {
		    prio = sk;
		    allow = cl;
		    }
		else
		    {
		    prio = cl;
		    allow = sk;
		    }
		/* In theory we could have ciphers sent back that we
		 * don't want to use but that does not matter since we
		 * will check against the list we originally sent and
		 * for performance reasons we should not bother to match
		 * the two lists up just to check. */
		for (i=0; i<sk_SSL_CIPHER_num(prio); i++)
			{
			if (sk_SSL_CIPHER_find(allow,
					     sk_SSL_CIPHER_value(prio,i)) >= 0)
				break;
			}

		if (i >= sk_SSL_CIPHER_num(prio))
			{
			ssl2_return_error(s,SSL2_PE_NO_CIPHER);
			SSLerr(SSL_F_GET_SERVER_HELLO,SSL_R_NO_CIPHER_MATCH);
			return(-1);
			}
		s->session->cipher=sk_SSL_CIPHER_value(prio,i);


		if (s->session->peer != NULL) /* can't happen*/
			{
			ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR);
			SSLerr(SSL_F_GET_SERVER_HELLO, ERR_R_INTERNAL_ERROR);
			return(-1);
			}

		s->session->peer = s->session->sess_cert->peer_key->x509;
		/* peer_key->x509 has been set by ssl2_set_certificate. */
		CRYPTO_add(&s->session->peer->references, 1, CRYPTO_LOCK_X509);
		}

	if (s->session->peer != s->session->sess_cert->peer_key->x509)
		/* can't happen */
		{
		ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR);
		SSLerr(SSL_F_GET_SERVER_HELLO, ERR_R_INTERNAL_ERROR);
		return(-1);
		}
		
	s->s2->conn_id_length=s->s2->tmp.conn_id_length;
	if (s->s2->conn_id_length > sizeof s->s2->conn_id)
		{
		ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR);
		SSLerr(SSL_F_GET_SERVER_HELLO, SSL_R_SSL2_CONNECTION_ID_TOO_LONG);
		return -1;
		}
	memcpy(s->s2->conn_id,p,s->s2->tmp.conn_id_length);
	return(1);
	}

static int client_hello(SSL *s)
	{
	unsigned char *buf;
	unsigned char *p,*d;
/*	CIPHER **cipher;*/
	int i,n,j;

	buf=(unsigned char *)s->init_buf->data;
	if (s->state == SSL2_ST_SEND_CLIENT_HELLO_A)
		{
		if ((s->session == NULL) ||
			(s->session->ssl_version != s->version))
			{
			if (!ssl_get_new_session(s,0))
				{
				ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
				return(-1);
				}
			}
		/* else use the pre-loaded session */

		p=buf;					/* header */
		d=p+9;					/* data section */
		*(p++)=SSL2_MT_CLIENT_HELLO;		/* type */
		s2n(SSL2_VERSION,p);			/* version */
		n=j=0;

		n=ssl_cipher_list_to_bytes(s,SSL_get_ciphers(s),d);
		d+=n;

		if (n == 0)
			{
			SSLerr(SSL_F_CLIENT_HELLO,SSL_R_NO_CIPHERS_AVAILABLE);
			return(-1);
			}

		s2n(n,p);			/* cipher spec num bytes */

		if ((s->session->session_id_length > 0) &&
			(s->session->session_id_length <=
			SSL2_MAX_SSL_SESSION_ID_LENGTH))
			{
			i=s->session->session_id_length;
			s2n(i,p);		/* session id length */
			memcpy(d,s->session->session_id,(unsigned int)i);
			d+=i;
			}
		else
			{
			s2n(0,p);
			}

		s->s2->challenge_length=SSL2_CHALLENGE_LENGTH;
		s2n(SSL2_CHALLENGE_LENGTH,p);		/* challenge length */
		/*challenge id data*/
		RAND_pseudo_bytes(s->s2->challenge,SSL2_CHALLENGE_LENGTH);
		memcpy(d,s->s2->challenge,SSL2_CHALLENGE_LENGTH);
		d+=SSL2_CHALLENGE_LENGTH;

		s->state=SSL2_ST_SEND_CLIENT_HELLO_B;
		s->init_num=d-buf;
		s->init_off=0;
		}
	/* SSL2_ST_SEND_CLIENT_HELLO_B */
	return(ssl2_do_write(s));
	}

static int client_master_key(SSL *s)
	{
	unsigned char *buf;
	unsigned char *p,*d;
	int clear,enc,karg,i;
	SSL_SESSION *sess;
	const EVP_CIPHER *c;
	const EVP_MD *md;

	buf=(unsigned char *)s->init_buf->data;
	if (s->state == SSL2_ST_SEND_CLIENT_MASTER_KEY_A)
		{

		if (!ssl_cipher_get_evp(s->session,&c,&md,NULL))
			{
			ssl2_return_error(s,SSL2_PE_NO_CIPHER);
			SSLerr(SSL_F_CLIENT_MASTER_KEY,SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS);
			return(-1);
			}
		sess=s->session;
		p=buf;
		d=p+10;
		*(p++)=SSL2_MT_CLIENT_MASTER_KEY;/* type */

		i=ssl_put_cipher_by_char(s,sess->cipher,p);
		p+=i;

		/* make key_arg data */
		i=EVP_CIPHER_iv_length(c);
		sess->key_arg_length=i;
		if (i > SSL_MAX_KEY_ARG_LENGTH)
			{
			ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR);
			SSLerr(SSL_F_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR);
			return -1;
			}
		if (i > 0) RAND_pseudo_bytes(sess->key_arg,i);

		/* make a master key */
		i=EVP_CIPHER_key_length(c);
		sess->master_key_length=i;
		if (i > 0)
			{
			if (i > sizeof sess->master_key)
				{
				ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR);
				SSLerr(SSL_F_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR);
				return -1;
				}
			if (RAND_bytes(sess->master_key,i) <= 0)
				{
				ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
				return(-1);
				}
			}

		if (sess->cipher->algorithm2 & SSL2_CF_8_BYTE_ENC)
			enc=8;
		else if (SSL_C_IS_EXPORT(sess->cipher))
			enc=5;
		else
			enc=i;

		if (i < enc)
			{
			ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
			SSLerr(SSL_F_CLIENT_MASTER_KEY,SSL_R_CIPHER_TABLE_SRC_ERROR);
			return(-1);
			}
		clear=i-enc;
		s2n(clear,p);
		memcpy(d,sess->master_key,(unsigned int)clear);
		d+=clear;

		enc=ssl_rsa_public_encrypt(sess->sess_cert,enc,
			&(sess->master_key[clear]),d,
			(s->s2->ssl2_rollback)?RSA_SSLV23_PADDING:RSA_PKCS1_PADDING);
		if (enc <= 0)
			{
			ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
			SSLerr(SSL_F_CLIENT_MASTER_KEY,SSL_R_PUBLIC_KEY_ENCRYPT_ERROR);
			return(-1);
			}
#ifdef PKCS1_CHECK
		if (s->options & SSL_OP_PKCS1_CHECK_1) d[1]++;
		if (s->options & SSL_OP_PKCS1_CHECK_2)
			sess->master_key[clear]++;
#endif
		s2n(enc,p);
		d+=enc;
		karg=sess->key_arg_length;	
		s2n(karg,p); /* key arg size */
		if (karg > sizeof sess->key_arg)
			{
			ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
			SSLerr(SSL_F_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR);
			return -1;
			}
		memcpy(d,sess->key_arg,(unsigned int)karg);
		d+=karg;

		s->state=SSL2_ST_SEND_CLIENT_MASTER_KEY_B;
		s->init_num=d-buf;
		s->init_off=0;
		}

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

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

	if (s->state == SSL2_ST_SEND_CLIENT_FINISHED_A)
		{
		p=(unsigned char *)s->init_buf->data;
		*(p++)=SSL2_MT_CLIENT_FINISHED;
		if (s->s2->conn_id_length > sizeof s->s2->conn_id)
			{
			SSLerr(SSL_F_CLIENT_FINISHED, ERR_R_INTERNAL_ERROR);
			return -1;
			}
		memcpy(p,s->s2->conn_id,(unsigned int)s->s2->conn_id_length);

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

/* read the data and then respond */
static int client_certificate(SSL *s)
	{
	unsigned char *buf;
	unsigned char *p,*d;
	int i;
	unsigned int n;
	int cert_ch_len;
	unsigned char *cert_ch;

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

	/* We have a cert associated with the SSL, so attach it to
	 * the session if it does not have one */

	if (s->state == SSL2_ST_SEND_CLIENT_CERTIFICATE_A)
		{
		i=ssl2_read(s,(char *)&(buf[s->init_num]),
			SSL2_MAX_CERT_CHALLENGE_LENGTH+2-s->init_num);
		if (i<(SSL2_MIN_CERT_CHALLENGE_LENGTH+2-s->init_num))
			return(ssl2_part_read(s,SSL_F_CLIENT_CERTIFICATE,i));
		s->init_num += i;
		if (s->msg_callback)
			s->msg_callback(0, s->version, 0, buf, (size_t)s->init_num, s, s->msg_callback_arg); /* REQUEST-CERTIFICATE */

		/* type=buf[0]; */
		/* type eq x509 */
		if (buf[1] != SSL2_AT_MD5_WITH_RSA_ENCRYPTION)
			{
			ssl2_return_error(s,SSL2_PE_UNSUPPORTED_CERTIFICATE_TYPE);
			SSLerr(SSL_F_CLIENT_CERTIFICATE,SSL_R_BAD_AUTHENTICATION_TYPE);
			return(-1);
			}

		if ((s->cert == NULL) ||
			(s->cert->key->x509 == NULL) ||
			(s->cert->key->privatekey == NULL))
			{
			s->state=SSL2_ST_X509_GET_CLIENT_CERTIFICATE;
			}
		else
			s->state=SSL2_ST_SEND_CLIENT_CERTIFICATE_C;
		}

	cert_ch = buf + 2;
	cert_ch_len = s->init_num - 2;

	if (s->state == SSL2_ST_X509_GET_CLIENT_CERTIFICATE)
		{
		X509 *x509=NULL;
		EVP_PKEY *pkey=NULL;

		/* If we get an error we need to
		 * ssl->rwstate=SSL_X509_LOOKUP;
		 * return(error);
		 * We should then be retried when things are ok and we
		 * can get a cert or not */

		i=0;
		if (s->ctx->client_cert_cb != NULL)
			{
			i=s->ctx->client_cert_cb(s,&(x509),&(pkey));
			}

		if (i < 0)
			{
			s->rwstate=SSL_X509_LOOKUP;
			return(-1);
			}
		s->rwstate=SSL_NOTHING;

		if ((i == 1) && (pkey != NULL) && (x509 != NULL))
			{
			s->state=SSL2_ST_SEND_CLIENT_CERTIFICATE_C;
			if (	!SSL_use_certificate(s,x509) || 
				!SSL_use_PrivateKey(s,pkey))
				{
				i=0;
				}
			X509_free(x509);
			EVP_PKEY_free(pkey);
			}
		else if (i == 1)
			{
			if (x509 != NULL) X509_free(x509);
			if (pkey != NULL) EVP_PKEY_free(pkey);
			SSLerr(SSL_F_CLIENT_CERTIFICATE,SSL_R_BAD_DATA_RETURNED_BY_CALLBACK);
			i=0;
			}

		if (i == 0)
			{
			/* We have no client certificate to respond with
			 * so send the correct error message back */
			s->state=SSL2_ST_SEND_CLIENT_CERTIFICATE_B;
			p=buf;
			*(p++)=SSL2_MT_ERROR;
			s2n(SSL2_PE_NO_CERTIFICATE,p);
			s->init_off=0;
			s->init_num=3;
			/* Write is done at the end */
			}
		}

	if (s->state == SSL2_ST_SEND_CLIENT_CERTIFICATE_B)
		{
		return(ssl2_do_write(s));
		}

	if (s->state == SSL2_ST_SEND_CLIENT_CERTIFICATE_C)
		{
		EVP_MD_CTX ctx;

		/* ok, now we calculate the checksum
		 * do it first so we can reuse buf :-) */
		p=buf;
		EVP_MD_CTX_init(&ctx);
		EVP_SignInit_ex(&ctx,s->ctx->rsa_md5, NULL);
		EVP_SignUpdate(&ctx,s->s2->key_material,
			       s->s2->key_material_length);
		EVP_SignUpdate(&ctx,cert_ch,(unsigned int)cert_ch_len);
		n=i2d_X509(s->session->sess_cert->peer_key->x509,&p);
		EVP_SignUpdate(&ctx,buf,(unsigned int)n);

		p=buf;
		d=p+6;
		*(p++)=SSL2_MT_CLIENT_CERTIFICATE;
		*(p++)=SSL2_CT_X509_CERTIFICATE;
		n=i2d_X509(s->cert->key->x509,&d);
		s2n(n,p);

		if (!EVP_SignFinal(&ctx,d,&n,s->cert->key->privatekey))
			{
			/* this is not good.  If things have failed it
			 * means there so something wrong with the key.
			 * We will continue with a 0 length signature
			 */
			}
		EVP_MD_CTX_cleanup(&ctx);
		s2n(n,p);
		d+=n;

		s->state=SSL2_ST_SEND_CLIENT_CERTIFICATE_D;
		s->init_num=d-buf;
		s->init_off=0;
		}
	/* if (s->state == SSL2_ST_SEND_CLIENT_CERTIFICATE_D) */
	return(ssl2_do_write(s));
	}

static int get_server_verify(SSL *s)
	{
	unsigned char *p;
	int i, n, len;

	p=(unsigned char *)s->init_buf->data;
	if (s->state == SSL2_ST_GET_SERVER_VERIFY_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_SERVER_VERIFY,i));
		s->init_num += i;

		s->state= SSL2_ST_GET_SERVER_VERIFY_B;
		if (*p != SSL2_MT_SERVER_VERIFY)
			{
			if (p[0] != SSL2_MT_ERROR)
				{
				ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
				SSLerr(SSL_F_GET_SERVER_VERIFY,
					SSL_R_READ_WRONG_PACKET_TYPE);
				}
			else
				{
				SSLerr(SSL_F_GET_SERVER_VERIFY,SSL_R_PEER_ERROR);
				/* try to read the error message */
				i=ssl2_read(s,(char *)&(p[s->init_num]),3-s->init_num);
				return ssl2_part_read(s,SSL_F_GET_SERVER_VERIFY,i);
				}
			return(-1);
			}
		}
	
	p=(unsigned char *)s->init_buf->data;
	len = 1 + s->s2->challenge_length;
	n =  len - s->init_num;
	i = ssl2_read(s,(char *)&(p[s->init_num]),n);
	if (i < n)
		return(ssl2_part_read(s,SSL_F_GET_SERVER_VERIFY,i));
	if (s->msg_callback)
		s->msg_callback(0, s->version, 0, p, len, s, s->msg_callback_arg); /* SERVER-VERIFY */
	p += 1;

	if (memcmp(p,s->s2->challenge,s->s2->challenge_length) != 0)
		{
		ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
		SSLerr(SSL_F_GET_SERVER_VERIFY,SSL_R_CHALLENGE_IS_DIFFERENT);
		return(-1);
		}
	return(1);
	}

static int get_server_finished(SSL *s)
	{
	unsigned char *buf;
	unsigned char *p;
	int i, n, len;

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

		if (*p == SSL2_MT_REQUEST_CERTIFICATE)
			{
			s->state=SSL2_ST_SEND_CLIENT_CERTIFICATE_A;
			return(1);
			}
		else if (*p != SSL2_MT_SERVER_FINISHED)
			{
			if (p[0] != SSL2_MT_ERROR)
				{
				ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
				SSLerr(SSL_F_GET_SERVER_FINISHED,SSL_R_READ_WRONG_PACKET_TYPE);
				}
			else
				{
				SSLerr(SSL_F_GET_SERVER_FINISHED,SSL_R_PEER_ERROR);
				/* try to read the error message */
				i=ssl2_read(s,(char *)&(p[s->init_num]),3-s->init_num);
				return ssl2_part_read(s,SSL_F_GET_SERVER_VERIFY,i);
				}
			return(-1);
			}
		s->state=SSL2_ST_GET_SERVER_FINISHED_B;
		}

	len = 1 + SSL2_SSL_SESSION_ID_LENGTH;
	n = len - s->init_num;
	i = ssl2_read(s,(char *)&(buf[s->init_num]), n);
	if (i < n) /* XXX could be shorter than SSL2_SSL_SESSION_ID_LENGTH, that's the maximum */
		return(ssl2_part_read(s,SSL_F_GET_SERVER_FINISHED,i));
	s->init_num += i;
	if (s->msg_callback)
		s->msg_callback(0, s->version, 0, buf, (size_t)s->init_num, s, s->msg_callback_arg); /* SERVER-FINISHED */

	if (!s->hit) /* new session */
		{
		/* new session-id */
		/* Make sure we were not trying to re-use an old SSL_SESSION
		 * or bad things can happen */
		/* ZZZZZZZZZZZZZ */
		s->session->session_id_length=SSL2_SSL_SESSION_ID_LENGTH;
		memcpy(s->session->session_id,p+1,SSL2_SSL_SESSION_ID_LENGTH);
		}
	else
		{
		if (!(s->options & SSL_OP_MICROSOFT_SESS_ID_BUG))
			{
			if ((s->session->session_id_length > sizeof s->session->session_id)
			    || (0 != memcmp(buf + 1, s->session->session_id,
			                    (unsigned int)s->session->session_id_length)))
				{
				ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
				SSLerr(SSL_F_GET_SERVER_FINISHED,SSL_R_SSL_SESSION_ID_IS_DIFFERENT);
				return(-1);
				}
			}
		}
	s->state = SSL_ST_OK;
	return(1);
	}

/* loads in the certificate from the server */
int ssl2_set_certificate(SSL *s, int type, int len, unsigned char *data)
	{
	STACK_OF(X509) *sk=NULL;
	EVP_PKEY *pkey=NULL;
	SESS_CERT *sc=NULL;
	int i;
	X509 *x509=NULL;
	int ret=0;
	
	x509=d2i_X509(NULL,&data,(long)len);
	if (x509 == NULL)
		{
		SSLerr(SSL_F_SSL2_SET_CERTIFICATE,ERR_R_X509_LIB);
		goto err;
		}

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

	i=ssl_verify_cert_chain(s,sk);
		
	if ((s->verify_mode != SSL_VERIFY_NONE) && (!i))
		{
		SSLerr(SSL_F_SSL2_SET_CERTIFICATE,SSL_R_CERTIFICATE_VERIFY_FAILED);
		goto err;
		}
	ERR_clear_error(); /* but we keep s->verify_result */
	s->session->verify_result = s->verify_result;

	/* server's cert for this session */
	sc=ssl_sess_cert_new();
	if (sc == NULL)
		{
		ret= -1;
		goto err;
		}
	if (s->session->sess_cert) ssl_sess_cert_free(s->session->sess_cert);
	s->session->sess_cert=sc;

	sc->peer_pkeys[SSL_PKEY_RSA_ENC].x509=x509;
	sc->peer_key= &(sc->peer_pkeys[SSL_PKEY_RSA_ENC]);

	pkey=X509_get_pubkey(x509);
	x509=NULL;
	if (pkey == NULL)
		{
		SSLerr(SSL_F_SSL2_SET_CERTIFICATE,SSL_R_UNABLE_TO_EXTRACT_PUBLIC_KEY);
		goto err;
		}
	if (pkey->type != EVP_PKEY_RSA)
		{
		SSLerr(SSL_F_SSL2_SET_CERTIFICATE,SSL_R_PUBLIC_KEY_NOT_RSA);
		goto err;
		}

	if (!ssl_set_peer_cert_type(sc,SSL2_CT_X509_CERTIFICATE))
		goto err;
	ret=1;
err:
	sk_X509_free(sk);
	X509_free(x509);
	EVP_PKEY_free(pkey);
	return(ret);
	}

static int ssl_rsa_public_encrypt(SESS_CERT *sc, int len, unsigned char *from,
	     unsigned char *to, int padding)
	{
	EVP_PKEY *pkey=NULL;
	int i= -1;

	if ((sc == NULL) || (sc->peer_key->x509 == NULL) ||
		((pkey=X509_get_pubkey(sc->peer_key->x509)) == NULL))
		{
		SSLerr(SSL_F_SSL_RSA_PUBLIC_ENCRYPT,SSL_R_NO_PUBLICKEY);
		return(-1);
		}
	if (pkey->type != EVP_PKEY_RSA)
		{
		SSLerr(SSL_F_SSL_RSA_PUBLIC_ENCRYPT,SSL_R_PUBLIC_KEY_IS_NOT_RSA);
		goto end;
		}

	/* we have the public key */
	i=RSA_public_encrypt(len,from,to,pkey->pkey.rsa,padding);
	if (i < 0)
		SSLerr(SSL_F_SSL_RSA_PUBLIC_ENCRYPT,ERR_R_RSA_LIB);
end:
	EVP_PKEY_free(pkey);
	return(i);
	}
#else /* !OPENSSL_NO_SSL2 */

# if PEDANTIC
static void *dummy=&dummy;
# endif

#endif
