/* 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, const char *buf, int num);
static int ssl_read(BIO *h, char *buf, int size);
static int ssl_puts(BIO *h, const char *str);
static long ssl_ctrl(BIO *h, int cmd, long arg1, void *arg2);
static int ssl_new(BIO *h);
static int ssl_free(BIO *data);
static long ssl_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
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,
	ssl_callback_ctrl,
	};

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

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

	bs=(BIO_SSL *)OPENSSL_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)
		OPENSSL_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_ACCEPT:
		BIO_set_retry_special(b);
		retry_reason=BIO_RR_ACCEPT;
		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, const 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, void *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);
			}
		if (b->next_bio != NULL)
			{
			CRYPTO_add(&b->next_bio->references,1,CRYPTO_LOCK_BIO);
			}
		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:
		{
#if 0 /* FIXME: Should this be used?  -- Richard Levitte */
		SSLerr(SSL_F_SSL_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
		ret = -1;
#else
		ret=0;
#endif
		}
		break;
	case BIO_CTRL_GET_CALLBACK:
		{
		void (**fptr)(const SSL *xssl,int type,int val);

		fptr=(void (**)(const SSL *xssl,int type,int val))ptr;
		*fptr=SSL_get_info_callback(ssl);
		}
		break;
	default:
		ret=BIO_ctrl(ssl->rbio,cmd,num,ptr);
		break;
		}
	return(ret);
	}

static long ssl_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
	{
	SSL *ssl;
	BIO_SSL *bs;
	long ret=1;

	bs=(BIO_SSL *)b->ptr;
	ssl=bs->ssl;
	switch (cmd)
		{
	case BIO_CTRL_SET_CALLBACK:
		{
		/* FIXME: setting this via a completely different prototype
		   seems like a crap idea */
		SSL_set_info_callback(ssl,(void (*)(const SSL *,int,int))fp);
		}
		break;
	default:
		ret=BIO_callback_ctrl(ssl->rbio,cmd,fp);
		break;
		}
	return(ret);
	}

static int ssl_puts(BIO *bp, const 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)
	{
#ifndef OPENSSL_NO_SOCK
	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);
#endif
	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;
		}
	}
