/* 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_CHANNEL_ID_LOOKUP:
		BIO_set_retry_special(b);
		retry_reason=BIO_RR_SSL_CHANNEL_ID_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_CHANNEL_ID_LOOKUP:
		BIO_set_retry_special(b);
		retry_reason=BIO_RR_SSL_CHANNEL_ID_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);
			if (!ssl_new(b))
				return 0;
			}
		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:
		/* Only detach if we are the BIO explicitly being popped */
		if (b == ptr)
			{
			/* Shouldn't happen in practice because the
			 * rbio and wbio are the same when pushed.
			 */
			if (ssl->rbio != ssl->wbio)
				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)
	{
#ifndef OPENSSL_NO_SOCK
	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);
#endif
	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;
		}
	}
