/* ssl/bio_ssl.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 <stdlib.h>
#include <string.h>
#include <errno.h>
#include <openssl/crypto.h>
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/ssl.h>

static int ssl_write(BIO *h,char *buf,int num);
static int ssl_read(BIO *h,char *buf,int size);
static int ssl_puts(BIO *h,char *str);
static long ssl_ctrl(BIO *h,int cmd,long arg1,char *arg2);
static int ssl_new(BIO *h);
static int ssl_free(BIO *data);
typedef struct bio_ssl_st
	{
	SSL *ssl; /* The ssl handle :-) */
	/* re-negotiate every time the total number of bytes is this size */
	int num_renegotiates;
	unsigned long renegotiate_count;
	unsigned long byte_count;
	unsigned long renegotiate_timeout;
	unsigned long last_time;
	} BIO_SSL;

static BIO_METHOD methods_sslp=
	{
	BIO_TYPE_SSL,"ssl",
	ssl_write,
	ssl_read,
	ssl_puts,
	NULL, /* ssl_gets, */
	ssl_ctrl,
	ssl_new,
	ssl_free,
	};

BIO_METHOD *BIO_f_ssl(void)
	{
	return(&methods_sslp);
	}

static int ssl_new(BIO *bi)
	{
	BIO_SSL *bs;

	bs=(BIO_SSL *)Malloc(sizeof(BIO_SSL));
	if (bs == NULL)
		{
		BIOerr(BIO_F_SSL_NEW,ERR_R_MALLOC_FAILURE);
		return(0);
		}
	memset(bs,0,sizeof(BIO_SSL));
	bi->init=0;
	bi->ptr=(char *)bs;
	bi->flags=0;
	return(1);
	}

static int ssl_free(BIO *a)
	{
	BIO_SSL *bs;

	if (a == NULL) return(0);
	bs=(BIO_SSL *)a->ptr;
	if (bs->ssl != NULL) SSL_shutdown(bs->ssl);
	if (a->shutdown)
		{
		if (a->init && (bs->ssl != NULL))
			SSL_free(bs->ssl);
		a->init=0;
		a->flags=0;
		}
	if (a->ptr != NULL)
		Free(a->ptr);
	return(1);
	}
	
static int ssl_read(BIO *b, char *out, int outl)
	{
	int ret=1;
	BIO_SSL *sb;
	SSL *ssl;
	int retry_reason=0;
	int r=0;

	if (out == NULL) return(0);
	sb=(BIO_SSL *)b->ptr;
	ssl=sb->ssl;

	BIO_clear_retry_flags(b);

#if 0
	if (!SSL_is_init_finished(ssl))
		{
/*		ret=SSL_do_handshake(ssl); */
		if (ret > 0)
			{

			outflags=(BIO_FLAGS_READ|BIO_FLAGS_SHOULD_RETRY);
			ret= -1;
			goto end;
			}
		}
#endif
/*	if (ret > 0) */
	ret=SSL_read(ssl,out,outl);

	switch (SSL_get_error(ssl,ret))
		{
	case SSL_ERROR_NONE:
		if (ret <= 0) break;
		if (sb->renegotiate_count > 0)
			{
			sb->byte_count+=ret;
			if (sb->byte_count > sb->renegotiate_count)
				{
				sb->byte_count=0;
				sb->num_renegotiates++;
				SSL_renegotiate(ssl);
				r=1;
				}
			}
		if ((sb->renegotiate_timeout > 0) && (!r))
			{
			unsigned long tm;

			tm=(unsigned long)time(NULL);
			if (tm > sb->last_time+sb->renegotiate_timeout)
				{
				sb->last_time=tm;
				sb->num_renegotiates++;
				SSL_renegotiate(ssl);
				}
			}

		break;
	case SSL_ERROR_WANT_READ:
		BIO_set_retry_read(b);
		break;
	case SSL_ERROR_WANT_WRITE:
		BIO_set_retry_write(b);
		break;
	case SSL_ERROR_WANT_X509_LOOKUP:
		BIO_set_retry_special(b);
		retry_reason=BIO_RR_SSL_X509_LOOKUP;
		break;
	case SSL_ERROR_WANT_CONNECT:
		BIO_set_retry_special(b);
		retry_reason=BIO_RR_CONNECT;
		break;
	case SSL_ERROR_SYSCALL:
	case SSL_ERROR_SSL:
	case SSL_ERROR_ZERO_RETURN:
	default:
		break;
		}

	b->retry_reason=retry_reason;
	return(ret);
	}

static int ssl_write(BIO *b, char *out, int outl)
	{
	int ret,r=0;
	int retry_reason=0;
	SSL *ssl;
	BIO_SSL *bs;

	if (out == NULL) return(0);
	bs=(BIO_SSL *)b->ptr;
	ssl=bs->ssl;

	BIO_clear_retry_flags(b);

/*	ret=SSL_do_handshake(ssl);
	if (ret > 0) */
	ret=SSL_write(ssl,out,outl);

	switch (SSL_get_error(ssl,ret))
		{
	case SSL_ERROR_NONE:
		if (ret <= 0) break;
		if (bs->renegotiate_count > 0)
			{
			bs->byte_count+=ret;
			if (bs->byte_count > bs->renegotiate_count)
				{
				bs->byte_count=0;
				bs->num_renegotiates++;
				SSL_renegotiate(ssl);
				r=1;
				}
			}
		if ((bs->renegotiate_timeout > 0) && (!r))
			{
			unsigned long tm;

			tm=(unsigned long)time(NULL);
			if (tm > bs->last_time+bs->renegotiate_timeout)
				{
				bs->last_time=tm;
				bs->num_renegotiates++;
				SSL_renegotiate(ssl);
				}
			}
		break;
	case SSL_ERROR_WANT_WRITE:
		BIO_set_retry_write(b);
		break;
	case SSL_ERROR_WANT_READ:
		BIO_set_retry_read(b);
		break;
	case SSL_ERROR_WANT_X509_LOOKUP:
		BIO_set_retry_special(b);
		retry_reason=BIO_RR_SSL_X509_LOOKUP;
		break;
	case SSL_ERROR_WANT_CONNECT:
		BIO_set_retry_special(b);
		retry_reason=BIO_RR_CONNECT;
	case SSL_ERROR_SYSCALL:
	case SSL_ERROR_SSL:
	default:
		break;
		}

	b->retry_reason=retry_reason;
	return(ret);
	}

static long ssl_ctrl(BIO *b, int cmd, long num, char *ptr)
	{
	SSL **sslp,*ssl;
	BIO_SSL *bs;
	BIO *dbio,*bio;
	long ret=1;

	bs=(BIO_SSL *)b->ptr;
	ssl=bs->ssl;
	if ((ssl == NULL)  && (cmd != BIO_C_SET_SSL))
		return(0);
	switch (cmd)
		{
	case BIO_CTRL_RESET:
		SSL_shutdown(ssl);

		if (ssl->handshake_func == ssl->method->ssl_connect)
			SSL_set_connect_state(ssl);
		else if (ssl->handshake_func == ssl->method->ssl_accept)
			SSL_set_accept_state(ssl);

		SSL_clear(ssl);

		if (b->next_bio != NULL)
			ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
		else if (ssl->rbio != NULL)
			ret=BIO_ctrl(ssl->rbio,cmd,num,ptr);
		else
			ret=1;
		break;
	case BIO_CTRL_INFO:
		ret=0;
		break;
	case BIO_C_SSL_MODE:
		if (num) /* client mode */
			SSL_set_connect_state(ssl);
		else
			SSL_set_accept_state(ssl);
		break;
	case BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT:
		ret=bs->renegotiate_timeout;
		if (num < 60) num=5;
		bs->renegotiate_timeout=(unsigned long)num;
		bs->last_time=(unsigned long)time(NULL);
		break;
	case BIO_C_SET_SSL_RENEGOTIATE_BYTES:
		ret=bs->renegotiate_count;
		if ((long)num >=512)
			bs->renegotiate_count=(unsigned long)num;
		break;
	case BIO_C_GET_SSL_NUM_RENEGOTIATES:
		ret=bs->num_renegotiates;
		break;
	case BIO_C_SET_SSL:
		if (ssl != NULL)
			ssl_free(b);
		b->shutdown=(int)num;
		ssl=(SSL *)ptr;
		((BIO_SSL *)b->ptr)->ssl=ssl;
		bio=SSL_get_rbio(ssl);
		if (bio != NULL)
			{
			if (b->next_bio != NULL)
				BIO_push(bio,b->next_bio);
			b->next_bio=bio;
			CRYPTO_add(&bio->references,1,CRYPTO_LOCK_BIO);
			}
		b->init=1;
		break;
	case BIO_C_GET_SSL:
		if (ptr != NULL)
			{
			sslp=(SSL **)ptr;
			*sslp=ssl;
			}
		else
			ret=0;
		break;
	case BIO_CTRL_GET_CLOSE:
		ret=b->shutdown;
		break;
	case BIO_CTRL_SET_CLOSE:
		b->shutdown=(int)num;
		break;
	case BIO_CTRL_WPENDING:
		ret=BIO_ctrl(ssl->wbio,cmd,num,ptr);
		break;
	case BIO_CTRL_PENDING:
		ret=SSL_pending(ssl);
		if (ret == 0)
			ret=BIO_pending(ssl->rbio);
		break;
	case BIO_CTRL_FLUSH:
		BIO_clear_retry_flags(b);
		ret=BIO_ctrl(ssl->wbio,cmd,num,ptr);
		BIO_copy_next_retry(b);
		break;
	case BIO_CTRL_PUSH:
		if ((b->next_bio != NULL) && (b->next_bio != ssl->rbio))
			{
			SSL_set_bio(ssl,b->next_bio,b->next_bio);
			CRYPTO_add(&b->next_bio->references,1,CRYPTO_LOCK_BIO);
			}
		break;
	case BIO_CTRL_POP:
		/* ugly bit of a hack */
		if (ssl->rbio != ssl->wbio) /* we are in trouble :-( */
			{
			BIO_free_all(ssl->wbio);
			}
		ssl->wbio=NULL;
		ssl->rbio=NULL;
		break;
	case BIO_C_DO_STATE_MACHINE:
		BIO_clear_retry_flags(b);

		b->retry_reason=0;
		ret=(int)SSL_do_handshake(ssl);

		switch (SSL_get_error(ssl,(int)ret))
			{
		case SSL_ERROR_WANT_READ:
			BIO_set_flags(b,
				BIO_FLAGS_READ|BIO_FLAGS_SHOULD_RETRY);
			break;
		case SSL_ERROR_WANT_WRITE:
			BIO_set_flags(b,
				BIO_FLAGS_WRITE|BIO_FLAGS_SHOULD_RETRY);
			break;
		case SSL_ERROR_WANT_CONNECT:
			BIO_set_flags(b,
				BIO_FLAGS_IO_SPECIAL|BIO_FLAGS_SHOULD_RETRY);
			b->retry_reason=b->next_bio->retry_reason;
			break;
		default:
			break;
			}
		break;
	case BIO_CTRL_DUP:
		dbio=(BIO *)ptr;
		if (((BIO_SSL *)dbio->ptr)->ssl != NULL)
			SSL_free(((BIO_SSL *)dbio->ptr)->ssl);
		((BIO_SSL *)dbio->ptr)->ssl=SSL_dup(ssl);
		((BIO_SSL *)dbio->ptr)->renegotiate_count=
			((BIO_SSL *)b->ptr)->renegotiate_count;
		((BIO_SSL *)dbio->ptr)->byte_count=
			((BIO_SSL *)b->ptr)->byte_count;
		((BIO_SSL *)dbio->ptr)->renegotiate_timeout=
			((BIO_SSL *)b->ptr)->renegotiate_timeout;
		((BIO_SSL *)dbio->ptr)->last_time=
			((BIO_SSL *)b->ptr)->last_time;
		ret=(((BIO_SSL *)dbio->ptr)->ssl != NULL);
		break;
	case BIO_C_GET_FD:
		ret=BIO_ctrl(ssl->rbio,cmd,num,ptr);
		break;
	case BIO_CTRL_SET_CALLBACK:
		SSL_set_info_callback(ssl,(void (*)())ptr);
		break;
	case BIO_CTRL_GET_CALLBACK:
		{
		void (**fptr)();

		fptr=(void (**)())ptr;
		*fptr=SSL_get_info_callback(ssl);
		}
		break;
	default:
		ret=BIO_ctrl(ssl->rbio,cmd,num,ptr);
		break;
		}
	return(ret);
	}

static int ssl_puts(BIO *bp, char *str)
	{
	int n,ret;

	n=strlen(str);
	ret=BIO_write(bp,str,n);
	return(ret);
	}

BIO *BIO_new_buffer_ssl_connect(SSL_CTX *ctx)
	{
	BIO *ret=NULL,*buf=NULL,*ssl=NULL;

	if ((buf=BIO_new(BIO_f_buffer())) == NULL)
		return(NULL);
	if ((ssl=BIO_new_ssl_connect(ctx)) == NULL)
		goto err;
	if ((ret=BIO_push(buf,ssl)) == NULL)
		goto err;
	return(ret);
err:
	if (buf != NULL) BIO_free(buf);
	if (ssl != NULL) BIO_free(ssl);
	return(NULL);
	}

BIO *BIO_new_ssl_connect(SSL_CTX *ctx)
	{
	BIO *ret=NULL,*con=NULL,*ssl=NULL;

	if ((con=BIO_new(BIO_s_connect())) == NULL)
		return(NULL);
	if ((ssl=BIO_new_ssl(ctx,1)) == NULL)
		goto err;
	if ((ret=BIO_push(ssl,con)) == NULL)
		goto err;
	return(ret);
err:
	if (con != NULL) BIO_free(con);
	if (ret != NULL) BIO_free(ret);
	return(NULL);
	}

BIO *BIO_new_ssl(SSL_CTX *ctx, int client)
	{
	BIO *ret;
	SSL *ssl;

	if ((ret=BIO_new(BIO_f_ssl())) == NULL)
		return(NULL);
	if ((ssl=SSL_new(ctx)) == NULL)
		{
		BIO_free(ret);
		return(NULL);
		}
	if (client)
		SSL_set_connect_state(ssl);
	else
		SSL_set_accept_state(ssl);
		
	BIO_set_ssl(ret,ssl,BIO_CLOSE);
	return(ret);
	}

int BIO_ssl_copy_session_id(BIO *t, BIO *f)
	{
	t=BIO_find_type(t,BIO_TYPE_SSL);
	f=BIO_find_type(f,BIO_TYPE_SSL);
	if ((t == NULL) || (f == NULL))
		return(0);
	if (	(((BIO_SSL *)t->ptr)->ssl == NULL) || 
		(((BIO_SSL *)f->ptr)->ssl == NULL))
		return(0);
	SSL_copy_session_id(((BIO_SSL *)t->ptr)->ssl,((BIO_SSL *)f->ptr)->ssl);
	return(1);
	}

void BIO_ssl_shutdown(BIO *b)
	{
	SSL *s;

	while (b != NULL)
		{
		if (b->method->type == BIO_TYPE_SSL)
			{
			s=((BIO_SSL *)b->ptr)->ssl;
			SSL_shutdown(s);
			break;
			}
		b=b->next_bio;
		}
	}
