bio_lib.c revision 68651
155714Skris/* crypto/bio/bio_lib.c */
255714Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
355714Skris * All rights reserved.
455714Skris *
555714Skris * This package is an SSL implementation written
655714Skris * by Eric Young (eay@cryptsoft.com).
755714Skris * The implementation was written so as to conform with Netscapes SSL.
855714Skris *
955714Skris * This library is free for commercial and non-commercial use as long as
1055714Skris * the following conditions are aheared to.  The following conditions
1155714Skris * apply to all code found in this distribution, be it the RC4, RSA,
1255714Skris * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
1355714Skris * included with this distribution is covered by the same copyright terms
1455714Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com).
1555714Skris *
1655714Skris * Copyright remains Eric Young's, and as such any Copyright notices in
1755714Skris * the code are not to be removed.
1855714Skris * If this package is used in a product, Eric Young should be given attribution
1955714Skris * as the author of the parts of the library used.
2055714Skris * This can be in the form of a textual message at program startup or
2155714Skris * in documentation (online or textual) provided with the package.
2255714Skris *
2355714Skris * Redistribution and use in source and binary forms, with or without
2455714Skris * modification, are permitted provided that the following conditions
2555714Skris * are met:
2655714Skris * 1. Redistributions of source code must retain the copyright
2755714Skris *    notice, this list of conditions and the following disclaimer.
2855714Skris * 2. Redistributions in binary form must reproduce the above copyright
2955714Skris *    notice, this list of conditions and the following disclaimer in the
3055714Skris *    documentation and/or other materials provided with the distribution.
3155714Skris * 3. All advertising materials mentioning features or use of this software
3255714Skris *    must display the following acknowledgement:
3355714Skris *    "This product includes cryptographic software written by
3455714Skris *     Eric Young (eay@cryptsoft.com)"
3555714Skris *    The word 'cryptographic' can be left out if the rouines from the library
3655714Skris *    being used are not cryptographic related :-).
3755714Skris * 4. If you include any Windows specific code (or a derivative thereof) from
3855714Skris *    the apps directory (application code) you must include an acknowledgement:
3955714Skris *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
4055714Skris *
4155714Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
4255714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4355714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4455714Skris * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
4555714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4655714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4755714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4955714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5055714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5155714Skris * SUCH DAMAGE.
5255714Skris *
5355714Skris * The licence and distribution terms for any publically available version or
5455714Skris * derivative of this code cannot be changed.  i.e. this code cannot simply be
5555714Skris * copied and put under another distribution licence
5655714Skris * [including the GNU Public Licence.]
5755714Skris */
5855714Skris
5955714Skris#include <stdio.h>
6055714Skris#include <errno.h>
6155714Skris#include <openssl/crypto.h>
6255714Skris#include "cryptlib.h"
6355714Skris#include <openssl/bio.h>
6455714Skris#include <openssl/stack.h>
6555714Skris
6659191Skrisstatic STACK_OF(CRYPTO_EX_DATA_FUNCS) *bio_meth=NULL;
6755714Skrisstatic int bio_meth_num=0;
6855714Skris
6955714SkrisBIO *BIO_new(BIO_METHOD *method)
7055714Skris	{
7155714Skris	BIO *ret=NULL;
7255714Skris
7368651Skris	ret=(BIO *)OPENSSL_malloc(sizeof(BIO));
7455714Skris	if (ret == NULL)
7555714Skris		{
7655714Skris		BIOerr(BIO_F_BIO_NEW,ERR_R_MALLOC_FAILURE);
7755714Skris		return(NULL);
7855714Skris		}
7955714Skris	if (!BIO_set(ret,method))
8055714Skris		{
8168651Skris		OPENSSL_free(ret);
8255714Skris		ret=NULL;
8355714Skris		}
8455714Skris	return(ret);
8555714Skris	}
8655714Skris
8755714Skrisint BIO_set(BIO *bio, BIO_METHOD *method)
8855714Skris	{
8955714Skris	bio->method=method;
9055714Skris	bio->callback=NULL;
9155714Skris	bio->cb_arg=NULL;
9255714Skris	bio->init=0;
9355714Skris	bio->shutdown=1;
9455714Skris	bio->flags=0;
9555714Skris	bio->retry_reason=0;
9655714Skris	bio->num=0;
9755714Skris	bio->ptr=NULL;
9855714Skris	bio->prev_bio=NULL;
9955714Skris	bio->next_bio=NULL;
10055714Skris	bio->references=1;
10155714Skris	bio->num_read=0L;
10255714Skris	bio->num_write=0L;
10359191Skris	CRYPTO_new_ex_data(bio_meth,bio,&bio->ex_data);
10455714Skris	if (method->create != NULL)
10555714Skris		if (!method->create(bio))
10655714Skris			return(0);
10755714Skris	return(1);
10855714Skris	}
10955714Skris
11055714Skrisint BIO_free(BIO *a)
11155714Skris	{
11255714Skris	int ret=0,i;
11355714Skris
11455714Skris	if (a == NULL) return(0);
11555714Skris
11655714Skris	i=CRYPTO_add(&a->references,-1,CRYPTO_LOCK_BIO);
11755714Skris#ifdef REF_PRINT
11855714Skris	REF_PRINT("BIO",a);
11955714Skris#endif
12055714Skris	if (i > 0) return(1);
12155714Skris#ifdef REF_CHECK
12255714Skris	if (i < 0)
12355714Skris		{
12455714Skris		fprintf(stderr,"BIO_free, bad reference count\n");
12555714Skris		abort();
12655714Skris		}
12755714Skris#endif
12855714Skris	if ((a->callback != NULL) &&
12955714Skris		((i=(int)a->callback(a,BIO_CB_FREE,NULL,0,0L,1L)) <= 0))
13055714Skris			return(i);
13155714Skris
13259191Skris	CRYPTO_free_ex_data(bio_meth,a,&a->ex_data);
13355714Skris
13455714Skris	if ((a->method == NULL) || (a->method->destroy == NULL)) return(1);
13555714Skris	ret=a->method->destroy(a);
13668651Skris	OPENSSL_free(a);
13755714Skris	return(1);
13855714Skris	}
13955714Skris
14068651Skrisvoid BIO_vfree(BIO *a)
14168651Skris    { BIO_free(a); }
14268651Skris
14355714Skrisint BIO_read(BIO *b, void *out, int outl)
14455714Skris	{
14555714Skris	int i;
14655714Skris	long (*cb)();
14755714Skris
14855714Skris	if ((b == NULL) || (b->method == NULL) || (b->method->bread == NULL))
14955714Skris		{
15055714Skris		BIOerr(BIO_F_BIO_READ,BIO_R_UNSUPPORTED_METHOD);
15155714Skris		return(-2);
15255714Skris		}
15355714Skris
15455714Skris	cb=b->callback;
15555714Skris	if ((cb != NULL) &&
15655714Skris		((i=(int)cb(b,BIO_CB_READ,out,outl,0L,1L)) <= 0))
15755714Skris			return(i);
15855714Skris
15955714Skris	if (!b->init)
16055714Skris		{
16155714Skris		BIOerr(BIO_F_BIO_READ,BIO_R_UNINITIALIZED);
16255714Skris		return(-2);
16355714Skris		}
16455714Skris
16555714Skris	i=b->method->bread(b,out,outl);
16655714Skris
16755714Skris	if (i > 0) b->num_read+=(unsigned long)i;
16855714Skris
16955714Skris	if (cb != NULL)
17055714Skris		i=(int)cb(b,BIO_CB_READ|BIO_CB_RETURN,out,outl,
17155714Skris			0L,(long)i);
17255714Skris	return(i);
17355714Skris	}
17455714Skris
17559191Skrisint BIO_write(BIO *b, const void *in, int inl)
17655714Skris	{
17755714Skris	int i;
17855714Skris	long (*cb)();
17955714Skris
18055714Skris	if (b == NULL)
18155714Skris		return(0);
18255714Skris
18355714Skris	cb=b->callback;
18455714Skris	if ((b->method == NULL) || (b->method->bwrite == NULL))
18555714Skris		{
18655714Skris		BIOerr(BIO_F_BIO_WRITE,BIO_R_UNSUPPORTED_METHOD);
18755714Skris		return(-2);
18855714Skris		}
18955714Skris
19055714Skris	if ((cb != NULL) &&
19155714Skris		((i=(int)cb(b,BIO_CB_WRITE,in,inl,0L,1L)) <= 0))
19255714Skris			return(i);
19355714Skris
19455714Skris	if (!b->init)
19555714Skris		{
19655714Skris		BIOerr(BIO_F_BIO_WRITE,BIO_R_UNINITIALIZED);
19755714Skris		return(-2);
19855714Skris		}
19955714Skris
20055714Skris	i=b->method->bwrite(b,in,inl);
20155714Skris
20255714Skris	if (i > 0) b->num_write+=(unsigned long)i;
20355714Skris
20468651Skris	if (cb != NULL)
20555714Skris		i=(int)cb(b,BIO_CB_WRITE|BIO_CB_RETURN,in,inl,
20655714Skris			0L,(long)i);
20755714Skris	return(i);
20855714Skris	}
20955714Skris
21055714Skrisint BIO_puts(BIO *b, const char *in)
21155714Skris	{
21255714Skris	int i;
21355714Skris	long (*cb)();
21455714Skris
21555714Skris	if ((b == NULL) || (b->method == NULL) || (b->method->bputs == NULL))
21655714Skris		{
21755714Skris		BIOerr(BIO_F_BIO_PUTS,BIO_R_UNSUPPORTED_METHOD);
21855714Skris		return(-2);
21955714Skris		}
22055714Skris
22155714Skris	cb=b->callback;
22255714Skris
22355714Skris	if ((cb != NULL) &&
22455714Skris		((i=(int)cb(b,BIO_CB_PUTS,in,0,0L,1L)) <= 0))
22555714Skris			return(i);
22655714Skris
22755714Skris	if (!b->init)
22855714Skris		{
22955714Skris		BIOerr(BIO_F_BIO_PUTS,BIO_R_UNINITIALIZED);
23055714Skris		return(-2);
23155714Skris		}
23255714Skris
23355714Skris	i=b->method->bputs(b,in);
23455714Skris
23568651Skris	if (i > 0) b->num_write+=(unsigned long)i;
23668651Skris
23755714Skris	if (cb != NULL)
23855714Skris		i=(int)cb(b,BIO_CB_PUTS|BIO_CB_RETURN,in,0,
23955714Skris			0L,(long)i);
24055714Skris	return(i);
24155714Skris	}
24255714Skris
24355714Skrisint BIO_gets(BIO *b, char *in, int inl)
24455714Skris	{
24555714Skris	int i;
24655714Skris	long (*cb)();
24755714Skris
24855714Skris	if ((b == NULL) || (b->method == NULL) || (b->method->bgets == NULL))
24955714Skris		{
25055714Skris		BIOerr(BIO_F_BIO_GETS,BIO_R_UNSUPPORTED_METHOD);
25155714Skris		return(-2);
25255714Skris		}
25355714Skris
25455714Skris	cb=b->callback;
25555714Skris
25655714Skris	if ((cb != NULL) &&
25755714Skris		((i=(int)cb(b,BIO_CB_GETS,in,inl,0L,1L)) <= 0))
25855714Skris			return(i);
25955714Skris
26055714Skris	if (!b->init)
26155714Skris		{
26255714Skris		BIOerr(BIO_F_BIO_GETS,BIO_R_UNINITIALIZED);
26355714Skris		return(-2);
26455714Skris		}
26555714Skris
26655714Skris	i=b->method->bgets(b,in,inl);
26755714Skris
26855714Skris	if (cb != NULL)
26955714Skris		i=(int)cb(b,BIO_CB_GETS|BIO_CB_RETURN,in,inl,
27055714Skris			0L,(long)i);
27155714Skris	return(i);
27255714Skris	}
27355714Skris
27455714Skrislong BIO_int_ctrl(BIO *b, int cmd, long larg, int iarg)
27555714Skris	{
27655714Skris	int i;
27755714Skris
27855714Skris	i=iarg;
27955714Skris	return(BIO_ctrl(b,cmd,larg,(char *)&i));
28055714Skris	}
28155714Skris
28255714Skrischar *BIO_ptr_ctrl(BIO *b, int cmd, long larg)
28355714Skris	{
28455714Skris	char *p=NULL;
28555714Skris
28655714Skris	if (BIO_ctrl(b,cmd,larg,(char *)&p) <= 0)
28755714Skris		return(NULL);
28855714Skris	else
28955714Skris		return(p);
29055714Skris	}
29155714Skris
29255714Skrislong BIO_ctrl(BIO *b, int cmd, long larg, void *parg)
29355714Skris	{
29455714Skris	long ret;
29555714Skris	long (*cb)();
29655714Skris
29755714Skris	if (b == NULL) return(0);
29855714Skris
29955714Skris	if ((b->method == NULL) || (b->method->ctrl == NULL))
30055714Skris		{
30155714Skris		BIOerr(BIO_F_BIO_CTRL,BIO_R_UNSUPPORTED_METHOD);
30255714Skris		return(-2);
30355714Skris		}
30455714Skris
30555714Skris	cb=b->callback;
30655714Skris
30755714Skris	if ((cb != NULL) &&
30855714Skris		((ret=cb(b,BIO_CB_CTRL,parg,cmd,larg,1L)) <= 0))
30955714Skris		return(ret);
31055714Skris
31155714Skris	ret=b->method->ctrl(b,cmd,larg,parg);
31255714Skris
31355714Skris	if (cb != NULL)
31455714Skris		ret=cb(b,BIO_CB_CTRL|BIO_CB_RETURN,parg,cmd,
31555714Skris			larg,ret);
31655714Skris	return(ret);
31755714Skris	}
31855714Skris
31968651Skrislong BIO_callback_ctrl(BIO *b, int cmd, void (*fp)(struct bio_st *, int, const char *, int, long, long))
32059191Skris	{
32159191Skris	long ret;
32259191Skris	long (*cb)();
32359191Skris
32459191Skris	if (b == NULL) return(0);
32559191Skris
32659191Skris	if ((b->method == NULL) || (b->method->callback_ctrl == NULL))
32759191Skris		{
32859191Skris		BIOerr(BIO_F_BIO_CTRL,BIO_R_UNSUPPORTED_METHOD);
32959191Skris		return(-2);
33059191Skris		}
33159191Skris
33259191Skris	cb=b->callback;
33359191Skris
33459191Skris	if ((cb != NULL) &&
33559191Skris		((ret=cb(b,BIO_CB_CTRL,(void *)&fp,cmd,0,1L)) <= 0))
33659191Skris		return(ret);
33759191Skris
33859191Skris	ret=b->method->callback_ctrl(b,cmd,fp);
33959191Skris
34059191Skris	if (cb != NULL)
34159191Skris		ret=cb(b,BIO_CB_CTRL|BIO_CB_RETURN,(void *)&fp,cmd,
34259191Skris			0,ret);
34359191Skris	return(ret);
34459191Skris	}
34559191Skris
34655714Skris/* It is unfortunate to duplicate in functions what the BIO_(w)pending macros
34755714Skris * do; but those macros have inappropriate return type, and for interfacing
34855714Skris * from other programming languages, C macros aren't much of a help anyway. */
34955714Skrissize_t BIO_ctrl_pending(BIO *bio)
35059191Skris	{
35155714Skris	return BIO_ctrl(bio, BIO_CTRL_PENDING, 0, NULL);
35255714Skris	}
35355714Skris
35455714Skrissize_t BIO_ctrl_wpending(BIO *bio)
35559191Skris	{
35655714Skris	return BIO_ctrl(bio, BIO_CTRL_WPENDING, 0, NULL);
35755714Skris	}
35855714Skris
35955714Skris
36055714Skris/* put the 'bio' on the end of b's list of operators */
36155714SkrisBIO *BIO_push(BIO *b, BIO *bio)
36255714Skris	{
36355714Skris	BIO *lb;
36455714Skris
36555714Skris	if (b == NULL) return(bio);
36655714Skris	lb=b;
36755714Skris	while (lb->next_bio != NULL)
36855714Skris		lb=lb->next_bio;
36955714Skris	lb->next_bio=bio;
37055714Skris	if (bio != NULL)
37155714Skris		bio->prev_bio=lb;
37255714Skris	/* called to do internal processing */
37355714Skris	BIO_ctrl(b,BIO_CTRL_PUSH,0,NULL);
37455714Skris	return(b);
37555714Skris	}
37655714Skris
37755714Skris/* Remove the first and return the rest */
37855714SkrisBIO *BIO_pop(BIO *b)
37955714Skris	{
38055714Skris	BIO *ret;
38155714Skris
38255714Skris	if (b == NULL) return(NULL);
38355714Skris	ret=b->next_bio;
38455714Skris
38555714Skris	if (b->prev_bio != NULL)
38655714Skris		b->prev_bio->next_bio=b->next_bio;
38755714Skris	if (b->next_bio != NULL)
38855714Skris		b->next_bio->prev_bio=b->prev_bio;
38955714Skris
39055714Skris	b->next_bio=NULL;
39155714Skris	b->prev_bio=NULL;
39255714Skris	BIO_ctrl(b,BIO_CTRL_POP,0,NULL);
39355714Skris	return(ret);
39455714Skris	}
39555714Skris
39655714SkrisBIO *BIO_get_retry_BIO(BIO *bio, int *reason)
39755714Skris	{
39855714Skris	BIO *b,*last;
39955714Skris
40055714Skris	b=last=bio;
40155714Skris	for (;;)
40255714Skris		{
40355714Skris		if (!BIO_should_retry(b)) break;
40455714Skris		last=b;
40555714Skris		b=b->next_bio;
40655714Skris		if (b == NULL) break;
40755714Skris		}
40855714Skris	if (reason != NULL) *reason=last->retry_reason;
40955714Skris	return(last);
41055714Skris	}
41155714Skris
41255714Skrisint BIO_get_retry_reason(BIO *bio)
41355714Skris	{
41455714Skris	return(bio->retry_reason);
41555714Skris	}
41655714Skris
41755714SkrisBIO *BIO_find_type(BIO *bio, int type)
41855714Skris	{
41955714Skris	int mt,mask;
42055714Skris
42168651Skris	if(!bio) return NULL;
42255714Skris	mask=type&0xff;
42355714Skris	do	{
42455714Skris		if (bio->method != NULL)
42555714Skris			{
42655714Skris			mt=bio->method->type;
42755714Skris
42855714Skris			if (!mask)
42955714Skris				{
43055714Skris				if (mt & type) return(bio);
43155714Skris				}
43255714Skris			else if (mt == type)
43355714Skris				return(bio);
43455714Skris			}
43555714Skris		bio=bio->next_bio;
43655714Skris		} while (bio != NULL);
43755714Skris	return(NULL);
43855714Skris	}
43955714Skris
44068651SkrisBIO *BIO_next(BIO *b)
44168651Skris	{
44268651Skris	if(!b) return NULL;
44368651Skris	return b->next_bio;
44468651Skris	}
44568651Skris
44655714Skrisvoid BIO_free_all(BIO *bio)
44755714Skris	{
44855714Skris	BIO *b;
44955714Skris	int ref;
45055714Skris
45155714Skris	while (bio != NULL)
45255714Skris		{
45355714Skris		b=bio;
45455714Skris		ref=b->references;
45555714Skris		bio=bio->next_bio;
45655714Skris		BIO_free(b);
45755714Skris		/* Since ref count > 1, don't free anyone else. */
45855714Skris		if (ref > 1) break;
45955714Skris		}
46055714Skris	}
46155714Skris
46255714SkrisBIO *BIO_dup_chain(BIO *in)
46355714Skris	{
46455714Skris	BIO *ret=NULL,*eoc=NULL,*bio,*new;
46555714Skris
46655714Skris	for (bio=in; bio != NULL; bio=bio->next_bio)
46755714Skris		{
46855714Skris		if ((new=BIO_new(bio->method)) == NULL) goto err;
46955714Skris		new->callback=bio->callback;
47055714Skris		new->cb_arg=bio->cb_arg;
47155714Skris		new->init=bio->init;
47255714Skris		new->shutdown=bio->shutdown;
47355714Skris		new->flags=bio->flags;
47455714Skris
47555714Skris		/* This will let SSL_s_sock() work with stdin/stdout */
47655714Skris		new->num=bio->num;
47755714Skris
47855714Skris		if (!BIO_dup_state(bio,(char *)new))
47955714Skris			{
48055714Skris			BIO_free(new);
48155714Skris			goto err;
48255714Skris			}
48355714Skris
48455714Skris		/* copy app data */
48555714Skris		if (!CRYPTO_dup_ex_data(bio_meth,&new->ex_data,&bio->ex_data))
48655714Skris			goto err;
48755714Skris
48855714Skris		if (ret == NULL)
48955714Skris			{
49055714Skris			eoc=new;
49155714Skris			ret=eoc;
49255714Skris			}
49355714Skris		else
49455714Skris			{
49555714Skris			BIO_push(eoc,new);
49655714Skris			eoc=new;
49755714Skris			}
49855714Skris		}
49955714Skris	return(ret);
50055714Skriserr:
50155714Skris	if (ret != NULL)
50255714Skris		BIO_free(ret);
50355714Skris	return(NULL);
50455714Skris	}
50555714Skris
50655714Skrisvoid BIO_copy_next_retry(BIO *b)
50755714Skris	{
50855714Skris	BIO_set_flags(b,BIO_get_retry_flags(b->next_bio));
50955714Skris	b->retry_reason=b->next_bio->retry_reason;
51055714Skris	}
51155714Skris
51259191Skrisint BIO_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
51359191Skris	     CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
51455714Skris	{
51555714Skris	bio_meth_num++;
51655714Skris	return(CRYPTO_get_ex_new_index(bio_meth_num-1,&bio_meth,
51755714Skris		argl,argp,new_func,dup_func,free_func));
51855714Skris	}
51955714Skris
52059191Skrisint BIO_set_ex_data(BIO *bio, int idx, void *data)
52155714Skris	{
52255714Skris	return(CRYPTO_set_ex_data(&(bio->ex_data),idx,data));
52355714Skris	}
52455714Skris
52559191Skrisvoid *BIO_get_ex_data(BIO *bio, int idx)
52655714Skris	{
52755714Skris	return(CRYPTO_get_ex_data(&(bio->ex_data),idx));
52855714Skris	}
52955714Skris
53059191Skrisunsigned long BIO_number_read(BIO *bio)
53159191Skris{
53259191Skris	if(bio) return bio->num_read;
53359191Skris	return 0;
53459191Skris}
53559191Skris
53659191Skrisunsigned long BIO_number_written(BIO *bio)
53759191Skris{
53859191Skris	if(bio) return bio->num_write;
53959191Skris	return 0;
54059191Skris}
54168651Skris
54268651SkrisIMPLEMENT_STACK_OF(BIO)
543