/* ssl/s3_pkt.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.]
 */

#include <stdio.h>
#include <errno.h>
#define USE_SOCKETS
#include <openssl/evp.h>
#include <openssl/buffer.h>
#include "ssl_locl.h"

static int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
			 unsigned int len);
static int ssl3_write_pending(SSL *s, int type, const unsigned char *buf,
			      unsigned int len);
static int ssl3_get_record(SSL *s);
static int do_compress(SSL *ssl);
static int do_uncompress(SSL *ssl);
static int do_change_cipher_spec(SSL *ssl);
static int ssl3_read_n(SSL *s, int n, int max, int extend)
	{
	int i,off,newb;

	/* if there is stuff still in the buffer from a previous read,
	 * and there is more than we want, take some. */
	if (s->s3->rbuf.left >= (int)n)
		{
		if (extend)
			s->packet_length+=n;
		else
			{
			s->packet= &(s->s3->rbuf.buf[s->s3->rbuf.offset]);
			s->packet_length=n;
			}
		s->s3->rbuf.left-=n;
		s->s3->rbuf.offset+=n;
		return(n);
		}

	/* else we need to read more data */
	if (!s->read_ahead) max=n;
	if (max > SSL3_RT_MAX_PACKET_SIZE)
		max=SSL3_RT_MAX_PACKET_SIZE;

	/* First check if there is some left or we want to extend */
	off=0;
	if (	(s->s3->rbuf.left != 0) ||
		((s->packet_length != 0) && extend))
		{
		newb=s->s3->rbuf.left;
		if (extend)
			{
			/* Copy bytes back to the front of the buffer 
			 * Take the bytes already pointed to by 'packet'
			 * and take the extra ones on the end. */
			off=s->packet_length;
			if (s->packet != s->s3->rbuf.buf)
				memcpy(s->s3->rbuf.buf,s->packet,newb+off);
			}
		else if (s->s3->rbuf.offset != 0)
			{ /* so the data is not at the start of the buffer */
			memcpy(s->s3->rbuf.buf,
				&(s->s3->rbuf.buf[s->s3->rbuf.offset]),newb);
			s->s3->rbuf.offset=0;
			}

		s->s3->rbuf.left=0;
		}
	else
		newb=0;

	/* So we now have 'newb' bytes at the front of 
	 * s->s3->rbuf.buf and need to read some more in on the end
	 * We start reading into the buffer at 's->s3->rbuf.offset'
	 */
	s->packet=s->s3->rbuf.buf;

	while (newb < n)
		{
		clear_sys_error();
		if (s->rbio != NULL)
			{
			s->rwstate=SSL_READING;
			i=BIO_read(s->rbio,
				(char *)&(s->s3->rbuf.buf[off+newb]),
				max-newb);
			}
		else
			{
			SSLerr(SSL_F_SSL3_READ_N,SSL_R_READ_BIO_NOT_SET);
			i= -1;
			}

		if (i <= 0)
			{
			s->s3->rbuf.left+=newb;
			return(i);
			}
		newb+=i;
		}

	/* record used data read */
	if (newb > n)
		{
		s->s3->rbuf.offset=n+off;
		s->s3->rbuf.left=newb-n;
		}
	else
		{
		s->s3->rbuf.offset=0;
		s->s3->rbuf.left=0;
		}

	if (extend)
		s->packet_length+=n;
	else
		s->packet_length+=n;
	return(n);
	}

/* Call this to get a new input record.
 * It will return <= 0 if more data is needed, normally due to an error
 * or non-blocking IO.
 * When it finishes, one packet has been decoded and can be found in
 * ssl->s3->rrec.type	- is the type of record
 * ssl->s3->rrec.data, 	- data
 * ssl->s3->rrec.length, - number of bytes
 */
static int ssl3_get_record(SSL *s)
	{
	int ssl_major,ssl_minor,al;
	int n,i,ret= -1;
	SSL3_BUFFER *rb;
	SSL3_RECORD *rr;
	SSL_SESSION *sess;
	unsigned char *p;
	unsigned char md[EVP_MAX_MD_SIZE];
	short version;
	unsigned int mac_size;
	int clear=0,extra;

	rr= &(s->s3->rrec);
	rb= &(s->s3->rbuf);
	sess=s->session;

	if (s->options & SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER)
		extra=SSL3_RT_MAX_EXTRA;
	else
		extra=0;

again:
	/* check if we have the header */
	if (	(s->rstate != SSL_ST_READ_BODY) ||
		(s->packet_length < SSL3_RT_HEADER_LENGTH)) 
		{
		n=ssl3_read_n(s,SSL3_RT_HEADER_LENGTH,
			SSL3_RT_MAX_PACKET_SIZE,0);
		if (n <= 0) return(n); /* error or non-blocking */
		s->rstate=SSL_ST_READ_BODY;

		p=s->packet;

		/* Pull apart the header into the SSL3_RECORD */
		rr->type= *(p++);
		ssl_major= *(p++);
		ssl_minor= *(p++);
		version=(ssl_major<<8)|ssl_minor;
		n2s(p,rr->length);

		/* Lets check version */
		if (s->first_packet)
			{
			s->first_packet=0;
			}
		else
			{
			if (version != s->version)
				{
				SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_WRONG_VERSION_NUMBER);
				/* Send back error using their
				 * version number :-) */
				s->version=version;
				al=SSL_AD_PROTOCOL_VERSION;
				goto f_err;
				}
			}

		if ((version>>8) != SSL3_VERSION_MAJOR)
			{
			SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_WRONG_VERSION_NUMBER);
			goto err;
			}

		if (rr->length > 
			(unsigned int)SSL3_RT_MAX_ENCRYPTED_LENGTH+extra)
			{
			al=SSL_AD_RECORD_OVERFLOW;
			SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_PACKET_LENGTH_TOO_LONG);
			goto f_err;
			}

		s->rstate=SSL_ST_READ_BODY;
		}

	/* get and decode the data */
	if (s->rstate == SSL_ST_READ_BODY)
		{
		if (rr->length > (s->packet_length-SSL3_RT_HEADER_LENGTH))
			{
			i=rr->length;
			/*-(s->packet_length-SSL3_RT_HEADER_LENGTH); */
			n=ssl3_read_n(s,i,i,1);
			if (n <= 0) return(n); /* error or non-blocking io */
			}
		s->rstate=SSL_ST_READ_HEADER;
		}

	/* At this point, we have the data in s->packet and there should be
	 * s->packet_length bytes, we must not 'overrun' this buffer :-)
	 * One of the following functions will copy the data from the
	 * s->packet buffer */

	rr->input= &(s->packet[SSL3_RT_HEADER_LENGTH]);

	/* ok, we can now read from 's->packet' data into 'rr'
	 * rr->input points at rr->length bytes, which
	 * need to be copied into rr->data by either
	 * the decryption or by the decompression
	 * When the data is 'copied' into the rr->data buffer,
	 * rr->input will be pointed at the new buffer */ 

	/* Set the state for the following operations */
	s->rstate=SSL_ST_READ_HEADER;

	/* We now have - encrypted [ MAC [ compressed [ plain ] ] ]
	 * rr->length bytes of encrypted compressed stuff. */

	/* check is not needed I belive */
	if (rr->length > (unsigned int)SSL3_RT_MAX_ENCRYPTED_LENGTH+extra)
		{
		al=SSL_AD_RECORD_OVERFLOW;
		SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_ENCRYPTED_LENGTH_TOO_LONG);
		goto f_err;
		}

	/* decrypt in place in 'rr->input' */
	rr->data=rr->input;

	if (!s->method->ssl3_enc->enc(s,0))
		{
		al=SSL_AD_DECRYPT_ERROR;
		goto f_err;
		}
#ifdef TLS_DEBUG
printf("dec %d\n",rr->length);
{ unsigned int z; for (z=0; z<rr->length; z++) printf("%02X%c",rr->data[z],((z+1)%16)?' ':'\n'); }
printf("\n");
#endif
	/* r->length is now the compressed data plus mac */
	if (	(sess == NULL) ||
		(s->enc_read_ctx == NULL) ||
		(s->read_hash == NULL))
		clear=1;

	if (!clear)
		{
		mac_size=EVP_MD_size(s->read_hash);

		if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+extra+mac_size)
			{
			al=SSL_AD_RECORD_OVERFLOW;
			SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_PRE_MAC_LENGTH_TOO_LONG);
			goto f_err;
			}
		/* check MAC for rr->input' */
		if (rr->length < mac_size)
			{
			al=SSL_AD_DECODE_ERROR;
			SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_LENGTH_TOO_SHORT);
			goto f_err;
			}
		rr->length-=mac_size;
		i=s->method->ssl3_enc->mac(s,md,0);
		if (memcmp(md,&(rr->data[rr->length]),mac_size) != 0)
			{
			al=SSL_AD_BAD_RECORD_MAC;
			SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_BAD_MAC_DECODE);
			ret= -1;
			goto f_err;
			}
		}

	/* r->length is now just compressed */
	if (s->expand != NULL)
		{
		if (rr->length > 
			(unsigned int)SSL3_RT_MAX_COMPRESSED_LENGTH+extra)
			{
			al=SSL_AD_RECORD_OVERFLOW;
			SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_COMPRESSED_LENGTH_TOO_LONG);
			goto f_err;
			}
		if (!do_uncompress(s))
			{
			al=SSL_AD_DECOMPRESSION_FAILURE;
			SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_BAD_DECOMPRESSION);
			goto f_err;
			}
		}

	if (rr->length > (unsigned int)SSL3_RT_MAX_PLAIN_LENGTH+extra)
		{
		al=SSL_AD_RECORD_OVERFLOW;
		SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_DATA_LENGTH_TOO_LONG);
		goto f_err;
		}

	rr->off=0;
	/* So at this point the following is true
	 * ssl->s3->rrec.type 	is the type of record
	 * ssl->s3->rrec.length	== number of bytes in record
	 * ssl->s3->rrec.off	== offset to first valid byte
	 * ssl->s3->rrec.data	== where to take bytes from, increment
	 *			   after use :-).
	 */

	/* we have pulled in a full packet so zero things */
	s->packet_length=0;

	/* just read a 0 length packet */
	if (rr->length == 0) goto again;

	return(1);
f_err:
	ssl3_send_alert(s,SSL3_AL_FATAL,al);
err:
	return(ret);
	}

static int do_uncompress(SSL *ssl)
	{
	int i;
	SSL3_RECORD *rr;

	rr= &(ssl->s3->rrec);
	i=COMP_expand_block(ssl->expand,rr->comp,
		SSL3_RT_MAX_PLAIN_LENGTH,rr->data,(int)rr->length);
	if (i < 0)
		return(0);
	else
		rr->length=i;
	rr->data=rr->comp;

	return(1);
	}

static int do_compress(SSL *ssl)
	{
	int i;
	SSL3_RECORD *wr;

	wr= &(ssl->s3->wrec);
	i=COMP_compress_block(ssl->compress,wr->data,
		SSL3_RT_MAX_COMPRESSED_LENGTH,
		wr->input,(int)wr->length);
	if (i < 0)
		return(0);
	else
		wr->length=i;

	wr->input=wr->data;
	return(1);
	}

/* Call this to write data
 * It will return <= 0 if not all data has been sent or non-blocking IO.
 */
int ssl3_write_bytes(SSL *s, int type, const void *_buf, int len)
	{
	const unsigned char *buf=_buf;
	unsigned int tot,n,nw;
	int i;

	s->rwstate=SSL_NOTHING;
	tot=s->s3->wnum;
	s->s3->wnum=0;

	if (SSL_in_init(s) && !s->in_handshake)
		{
		i=s->handshake_func(s);
		if (i < 0) return(i);
		if (i == 0)
			{
			SSLerr(SSL_F_SSL3_WRITE_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE);
			return(-1);
			}
		}

	n=(len-tot);
	for (;;)
		{
		if (n > SSL3_RT_MAX_PLAIN_LENGTH)
			nw=SSL3_RT_MAX_PLAIN_LENGTH;
		else
			nw=n;
			
		i=do_ssl3_write(s,type,&(buf[tot]),nw);
		if (i <= 0)
			{
			s->s3->wnum=tot;
			return(i);
			}

		if (type == SSL3_RT_HANDSHAKE)
			ssl3_finish_mac(s,&(buf[tot]),i);

		if (i == (int)n) return(tot+i);

		n-=i;
		tot+=i;
		}
	}

static int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
			 unsigned int len)
	{
	unsigned char *p,*plen;
	int i,mac_size,clear=0;
	SSL3_RECORD *wr;
	SSL3_BUFFER *wb;
	SSL_SESSION *sess;

	/* first check is there is a SSL3_RECORD still being written
	 * out.  This will happen with non blocking IO */
	if (s->s3->wbuf.left != 0)
		return(ssl3_write_pending(s,type,buf,len));

	/* If we have an alert to send, lets send it */
	if (s->s3->alert_dispatch)
		{
		i=ssl3_dispatch_alert(s);
		if (i <= 0)
			return(i);
		/* if it went, fall through and send more stuff */
		}

	if (len <= 0) return(len);
	
	wr= &(s->s3->wrec);
	wb= &(s->s3->wbuf);
	sess=s->session;

	if (	(sess == NULL) ||
		(s->enc_write_ctx == NULL) ||
		(s->write_hash == NULL))
		clear=1;

	if (clear)
		mac_size=0;
	else
		mac_size=EVP_MD_size(s->write_hash);

	p=wb->buf;

	/* write the header */
	*(p++)=type&0xff;
	wr->type=type;

	*(p++)=(s->version>>8);
	*(p++)=s->version&0xff;
	
	/* record where we are to write out packet length */
	plen=p; 
	p+=2;
	
	/* lets setup the record stuff. */
	wr->data=p;
	wr->length=(int)len;
	wr->input=(unsigned char *)buf;

	/* we now 'read' from wr->input, wr->length bytes into
	 * wr->data */

	/* first we compress */
	if (s->compress != NULL)
		{
		if (!do_compress(s))
			{
			SSLerr(SSL_F_DO_SSL3_WRITE,SSL_R_COMPRESSION_FAILURE);
			goto err;
			}
		}
	else
		{
		memcpy(wr->data,wr->input,wr->length);
		wr->input=wr->data;
		}

	/* we should still have the output to wr->data and the input
	 * from wr->input.  Length should be wr->length.
	 * wr->data still points in the wb->buf */

	if (mac_size != 0)
		{
		s->method->ssl3_enc->mac(s,&(p[wr->length]),1);
		wr->length+=mac_size;
		wr->input=p;
		wr->data=p;
		}

	/* ssl3_enc can only have an error on read */
	s->method->ssl3_enc->enc(s,1);

	/* record length after mac and block padding */
	s2n(wr->length,plen);

	/* we should now have
	 * wr->data pointing to the encrypted data, which is
	 * wr->length long */
	wr->type=type; /* not needed but helps for debugging */
	wr->length+=SSL3_RT_HEADER_LENGTH;

	/* Now lets setup wb */
	wb->left=wr->length;
	wb->offset=0;

	s->s3->wpend_tot=len;
	s->s3->wpend_buf=buf;
	s->s3->wpend_type=type;
	s->s3->wpend_ret=len;

	/* we now just need to write the buffer */
	return(ssl3_write_pending(s,type,buf,len));
err:
	return(-1);
	}

/* if s->s3->wbuf.left != 0, we need to call this */
static int ssl3_write_pending(SSL *s, int type, const unsigned char *buf,
			      unsigned int len)
	{
	int i;

/* XXXX */
	if ((s->s3->wpend_tot > (int)len) || (s->s3->wpend_buf != buf)
		|| (s->s3->wpend_type != type))
		{
		SSLerr(SSL_F_SSL3_WRITE_PENDING,SSL_R_BAD_WRITE_RETRY);
		return(-1);
		}

	for (;;)
		{
		clear_sys_error();
		if (s->wbio != NULL)
			{
			s->rwstate=SSL_WRITING;
			i=BIO_write(s->wbio,
				(char *)&(s->s3->wbuf.buf[s->s3->wbuf.offset]),
				(unsigned int)s->s3->wbuf.left);
			}
		else
			{
			SSLerr(SSL_F_SSL3_WRITE_PENDING,SSL_R_BIO_NOT_SET);
			i= -1;
			}
		if (i == s->s3->wbuf.left)
			{
			s->s3->wbuf.left=0;
			s->rwstate=SSL_NOTHING;
			return(s->s3->wpend_ret);
			}
		else if (i <= 0)
			return(i);
		s->s3->wbuf.offset+=i;
		s->s3->wbuf.left-=i;
		}
	}

int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len)
	{
	int al,i,j,n,ret;
	SSL3_RECORD *rr;
	void (*cb)()=NULL;
	BIO *bio;

	if (s->s3->rbuf.buf == NULL) /* Not initialize yet */
		if (!ssl3_setup_buffers(s))
			return(-1);

	if (!s->in_handshake && SSL_in_init(s))
		{
		i=s->handshake_func(s);
		if (i < 0) return(i);
		if (i == 0)
			{
			SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE);
			return(-1);
			}
		}
start:
	s->rwstate=SSL_NOTHING;

	/* s->s3->rrec.type	- is the type of record
	 * s->s3->rrec.data, 	- data
	 * s->s3->rrec.off, 	- ofset into 'data' for next read
	 * s->s3->rrec.length,	- number of bytes. */
	rr= &(s->s3->rrec);

	/* get new packet */
	if ((rr->length == 0) || (s->rstate == SSL_ST_READ_BODY))
		{
		ret=ssl3_get_record(s);
		if (ret <= 0) return(ret);
		}

	/* we now have a packet which can be read and processed */

	if (s->s3->change_cipher_spec && (rr->type != SSL3_RT_HANDSHAKE))
		{
		al=SSL_AD_UNEXPECTED_MESSAGE;
		SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_DATA_BETWEEN_CCS_AND_FINISHED);
		goto err;
		}

	/* If the other end has shutdown, throw anything we read away */
	if (s->shutdown & SSL_RECEIVED_SHUTDOWN)
		{
		rr->length=0;
		s->rwstate=SSL_NOTHING;
		return(0);
		}

	/* Check for an incoming 'Client Request' message */
	if ((rr->type == SSL3_RT_HANDSHAKE) && (rr->length == 4) &&
		(rr->data[0] == SSL3_MT_CLIENT_REQUEST) &&
		(s->session != NULL) && (s->session->cipher != NULL))
		{
		if ((rr->data[1] != 0) || (rr->data[2] != 0) ||
			(rr->data[3] != 0))
			{
			al=SSL_AD_DECODE_ERROR;
			SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_BAD_CLIENT_REQUEST);
			goto err;
			}

		if (SSL_is_init_finished(s) &&
			!(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) &&
			!s->s3->renegotiate)
			{
			ssl3_renegotiate(s);
			if (ssl3_renegotiate_check(s))
				{
				n=s->handshake_func(s);
				if (n < 0) return(n);
				if (n == 0)
					{
					SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE);
					return(-1);
					}
				}
			}
		rr->length=0;
/* ZZZ */	goto start;
		}

	/* if it is not the type we want, or we have shutdown and want
	 * the peer shutdown */
	if ((rr->type != type) || (s->shutdown & SSL_SENT_SHUTDOWN))
		{
		if (rr->type == SSL3_RT_ALERT)
			{
			if ((rr->length != 2) || (rr->off != 0))
				{
				al=SSL_AD_DECODE_ERROR;
				SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_BAD_ALERT_RECORD);
				goto f_err;
				}

			i=rr->data[0];
			n=rr->data[1];

			/* clear from buffer */
			rr->length=0;

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

			if (cb != NULL)
				{
				j=(i<<8)|n;
				cb(s,SSL_CB_READ_ALERT,j);
				}

			if (i == 1)
				{
				s->s3->warn_alert=n;
				if (n == SSL_AD_CLOSE_NOTIFY)
					{
					s->shutdown|=SSL_RECEIVED_SHUTDOWN;
					return(0);
					}
				}
			else if (i == 2)
				{
				char tmp[16];

				s->rwstate=SSL_NOTHING;
				s->s3->fatal_alert=n;
				SSLerr(SSL_F_SSL3_READ_BYTES,
					SSL_AD_REASON_OFFSET+n);
				sprintf(tmp,"%d",n);
				ERR_add_error_data(2,"SSL alert number ",tmp);
				s->shutdown|=SSL_RECEIVED_SHUTDOWN;
				SSL_CTX_remove_session(s->ctx,s->session);
				return(0);
				}
			else
				{
				al=SSL_AD_ILLEGAL_PARAMETER;
				SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_UNKNOWN_ALERT_TYPE);
				goto f_err;
				}

			rr->length=0;
			goto start;
			}

		if (s->shutdown & SSL_SENT_SHUTDOWN)
			{
			s->rwstate=SSL_NOTHING;
			rr->length=0;
			return(0);
			}

		if (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC)
			{
			if (	(rr->length != 1) || (rr->off != 0) ||
				(rr->data[0] != SSL3_MT_CCS))
				{
				i=SSL_AD_ILLEGAL_PARAMETER;
				SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_BAD_CHANGE_CIPHER_SPEC);
				goto err;
				}

			rr->length=0;
			s->s3->change_cipher_spec=1;
			if (!do_change_cipher_spec(s))
				goto err;
			else
				goto start;
			}

		/* else we have a handshake */
		if ((rr->type == SSL3_RT_HANDSHAKE) &&
			!s->in_handshake)
			{
			if (((s->state&SSL_ST_MASK) == SSL_ST_OK) &&
				!(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS))
				{
				s->state=SSL_ST_BEFORE|(s->server)
						?SSL_ST_ACCEPT
						:SSL_ST_CONNECT;
				s->new_session=1;
				}
			n=s->handshake_func(s);
			if (n < 0) return(n);
			if (n == 0)
				{
				SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE);
				return(-1);
				}

			/* In the case where we try to read application data
			 * the first time, but we trigger an SSL handshake, we
			 * return -1 with the retry option set.  I do this
			 * otherwise renegotiation can cause nasty problems 
			 * in the non-blocking world */

			s->rwstate=SSL_READING;
			bio=SSL_get_rbio(s);
			BIO_clear_retry_flags(bio);
			BIO_set_retry_read(bio);
			return(-1);
			}

		switch (rr->type)
			{
		default:
#ifndef NO_TLS
			/* TLS just ignores unknown message types */
			if (s->version == TLS1_VERSION)
				{
				goto start;
				}
#endif
		case SSL3_RT_CHANGE_CIPHER_SPEC:
		case SSL3_RT_ALERT:
		case SSL3_RT_HANDSHAKE:
			al=SSL_AD_UNEXPECTED_MESSAGE;
			SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_UNEXPECTED_RECORD);
			goto f_err;
		case SSL3_RT_APPLICATION_DATA:
			/* At this point, we were expecting something else,
			 * but have application data.  What we do is set the
			 * error, and return -1.  On the way out, if the
			 * library was running inside ssl3_read() and it makes
			 * sense to read application data at this point, we
			 * will indulge it.  This will mostly happen during
			 * session renegotiation.
			 */
			if (s->s3->in_read_app_data &&
				(s->s3->total_renegotiations != 0) &&
				((
				  (s->state & SSL_ST_CONNECT) &&
				  (s->state >= SSL3_ST_CW_CLNT_HELLO_A) &&
				  (s->state <= SSL3_ST_CR_SRVR_HELLO_A)
				 ) || (
				  (s->state & SSL_ST_ACCEPT) &&
				  (s->state <= SSL3_ST_SW_HELLO_REQ_A) &&
				  (s->state >= SSL3_ST_SR_CLNT_HELLO_A)
				 )
				))
				{
				s->s3->in_read_app_data=0;
				return(-1);
				}
			else
				{
				al=SSL_AD_UNEXPECTED_MESSAGE;
				SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_UNEXPECTED_RECORD);
				goto f_err;
				}
			}
		}

	/* make sure that we are not getting application data when we
	 * are doing a handshake for the first time */
	if (SSL_in_init(s) && (type == SSL3_RT_APPLICATION_DATA) &&
		(s->enc_read_ctx == NULL))
		{
		al=SSL_AD_UNEXPECTED_MESSAGE;
		SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_APP_DATA_IN_HANDSHAKE);
		goto f_err;
		}

	if (len <= 0) return(len);

	if ((unsigned int)len > rr->length)
		n=rr->length;
	else
		n=len;

	memcpy(buf,&(rr->data[rr->off]),(unsigned int)n);
	rr->length-=n;
	rr->off+=n;
	if (rr->length <= 0)
		{
		s->rstate=SSL_ST_READ_HEADER;
		rr->off=0;
		}

	if (type == SSL3_RT_HANDSHAKE)
		ssl3_finish_mac(s,buf,n);
	return(n);
f_err:
	ssl3_send_alert(s,SSL3_AL_FATAL,al);
err:
	return(-1);
	}

static int do_change_cipher_spec(SSL *s)
	{
	int i;
	unsigned char *sender;
	int slen;

	if (s->state & SSL_ST_ACCEPT)
		i=SSL3_CHANGE_CIPHER_SERVER_READ;
	else
		i=SSL3_CHANGE_CIPHER_CLIENT_READ;

	if (s->s3->tmp.key_block == NULL)
		{
		s->session->cipher=s->s3->tmp.new_cipher;
		if (!s->method->ssl3_enc->setup_key_block(s)) return(0);
		}

	if (!s->method->ssl3_enc->change_cipher_state(s,i))
		return(0);

	/* we have to record the message digest at
	 * this point so we can get it before we read
	 * the finished message */
	if (s->state & SSL_ST_CONNECT)
		{
		sender=s->method->ssl3_enc->server_finished;
		slen=s->method->ssl3_enc->server_finished_len;
		}
	else
		{
		sender=s->method->ssl3_enc->client_finished;
		slen=s->method->ssl3_enc->client_finished_len;
		}

	s->method->ssl3_enc->final_finish_mac(s,
		&(s->s3->finish_dgst1),
		&(s->s3->finish_dgst2),
		sender,slen,&(s->s3->tmp.finish_md[0]));

	return(1);
	}

int ssl3_do_write(SSL *s, int type)
	{
	int ret;

	ret=ssl3_write_bytes(s,type,&s->init_buf->data[s->init_off],
			     s->init_num);
	if (ret == s->init_num)
		return(1);
	if (ret < 0) return(-1);
	s->init_off+=ret;
	s->init_num-=ret;
	return(0);
	}

void ssl3_send_alert(SSL *s, int level, int desc)
	{
	/* Map tls/ssl alert value to correct one */
	desc=s->method->ssl3_enc->alert_value(desc);
	if (desc < 0) return;
	/* If a fatal one, remove from cache */
	if ((level == 2) && (s->session != NULL))
		SSL_CTX_remove_session(s->ctx,s->session);

	s->s3->alert_dispatch=1;
	s->s3->send_alert[0]=level;
	s->s3->send_alert[1]=desc;
	if (s->s3->wbuf.left == 0) /* data still being written out */
		ssl3_dispatch_alert(s);
	/* else data is still being written out, we will get written
	 * some time in the future */
	}

int ssl3_dispatch_alert(SSL *s)
	{
	int i,j;
	void (*cb)()=NULL;

	s->s3->alert_dispatch=0;
	i=do_ssl3_write(s,SSL3_RT_ALERT,&s->s3->send_alert[0],2);
	if (i <= 0)
		{
		s->s3->alert_dispatch=1;
		}
	else
		{
		/* If it is important, send it now.  If the message
		 * does not get sent due to non-blocking IO, we will
		 * not worry too much. */
		if (s->s3->send_alert[0] == SSL3_AL_FATAL)
			BIO_flush(s->wbio);

		if (s->info_callback != NULL)
			cb=s->info_callback;
		else if (s->ctx->info_callback != NULL)
			cb=s->ctx->info_callback;
		
		if (cb != NULL)
			{
			j=(s->s3->send_alert[0]<<8)|s->s3->send_alert[1];
			cb(s,SSL_CB_WRITE_ALERT,j);
			}
		}
	return(i);
	}

