X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=crypto%2Fbio%2Fbio_lib.c;h=b72688ea901c1b2e6f7a6cb0662c24bf3e29d6c0;hb=019a7aba4a05afee1e59c2f8656ba0b319b2213b;hp=78e896f9aec0d1077c77c32589ce7ab6398e4091;hpb=eda1f21f1af8b6f77327e7b37573af9c1ba73726;p=oweals%2Fopenssl.git diff --git a/crypto/bio/bio_lib.c b/crypto/bio/bio_lib.c index 78e896f9ae..b72688ea90 100644 --- a/crypto/bio/bio_lib.c +++ b/crypto/bio/bio_lib.c @@ -1,5 +1,5 @@ /* crypto/bio/bio_lib.c */ -/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * * This package is an SSL implementation written @@ -58,11 +58,15 @@ #include #include +#include #include "cryptlib.h" -#include "bio.h" +#include +#include -BIO *BIO_new(method) -BIO_METHOD *method; +static STACK *bio_meth=NULL; +static int bio_meth_num=0; + +BIO *BIO_new(BIO_METHOD *method) { BIO *ret=NULL; @@ -80,40 +84,40 @@ BIO_METHOD *method; return(ret); } -int BIO_set(bio,method) -BIO *bio; -BIO_METHOD *method; +int BIO_set(BIO *bio, BIO_METHOD *method) { bio->method=method; bio->callback=NULL; bio->cb_arg=NULL; bio->init=0; bio->shutdown=1; - bio->num=0; bio->flags=0; bio->retry_reason=0; + bio->num=0; bio->ptr=NULL; bio->prev_bio=NULL; bio->next_bio=NULL; bio->references=1; bio->num_read=0L; bio->num_write=0L; + CRYPTO_new_ex_data(bio_meth,(char *)bio,&bio->ex_data); if (method->create != NULL) if (!method->create(bio)) return(0); return(1); } -int BIO_free(a) -BIO *a; +int BIO_free(BIO *a) { int ret=0,i; if (a == NULL) return(0); i=CRYPTO_add(&a->references,-1,CRYPTO_LOCK_BIO); - - if (i > 0) return(1); +#ifdef REF_PRINT + REF_PRINT("BIO",a); +#endif + if (i > 0) return(1); #ifdef REF_CHECK if (i < 0) { @@ -125,18 +129,18 @@ BIO *a; ((i=(int)a->callback(a,BIO_CB_FREE,NULL,0,0L,1L)) <= 0)) return(i); + CRYPTO_free_ex_data(bio_meth,(char *)a,&a->ex_data); + if ((a->method == NULL) || (a->method->destroy == NULL)) return(1); ret=a->method->destroy(a); Free(a); return(1); } -int BIO_read(b,out,outl) -BIO *b; -char *out; -int outl; +int BIO_read(BIO *b, void *out, int outl) { int i; + long (*cb)(); if ((b == NULL) || (b->method == NULL) || (b->method->bread == NULL)) { @@ -144,62 +148,72 @@ int outl; return(-2); } - if ((b->callback != NULL) && - ((i=(int)b->callback(b,BIO_CB_READ,out,outl,0L,1L)) <= 0)) + cb=b->callback; + if ((cb != NULL) && + ((i=(int)cb(b,BIO_CB_READ,out,outl,0L,1L)) <= 0)) return(i); if (!b->init) { - BIOerr(BIO_F_BIO_READ,BIO_R_UNINITALISED); + BIOerr(BIO_F_BIO_READ,BIO_R_UNINITIALIZED); return(-2); } i=b->method->bread(b,out,outl); + if (i > 0) b->num_read+=(unsigned long)i; - if (b->callback != NULL) - i=(int)b->callback(b,BIO_CB_READ|BIO_CB_RETURN,out,outl, + if (cb != NULL) + i=(int)cb(b,BIO_CB_READ|BIO_CB_RETURN,out,outl, 0L,(long)i); return(i); } -int BIO_write(b,in,inl) -BIO *b; -char *in; -int inl; +int BIO_write(BIO *b, const char *in, int inl) { int i; + long (*cb)(); - if ((b == NULL) || (b->method == NULL) || (b->method->bwrite == NULL)) + if (b == NULL) + return(0); + + cb=b->callback; + if ((b->method == NULL) || (b->method->bwrite == NULL)) { BIOerr(BIO_F_BIO_WRITE,BIO_R_UNSUPPORTED_METHOD); return(-2); } - if ((b->callback != NULL) && - ((i=(int)b->callback(b,BIO_CB_WRITE,in,inl,0L,1L)) <= 0)) + if ((cb != NULL) && + ((i=(int)cb(b,BIO_CB_WRITE,in,inl,0L,1L)) <= 0)) return(i); if (!b->init) { - BIOerr(BIO_F_BIO_WRITE,BIO_R_UNINITALISED); + BIOerr(BIO_F_BIO_WRITE,BIO_R_UNINITIALIZED); return(-2); } i=b->method->bwrite(b,in,inl); + if (i > 0) b->num_write+=(unsigned long)i; - if (b->callback != NULL) - i=(int)b->callback(b,BIO_CB_WRITE|BIO_CB_RETURN,in,inl, + /* This is evil and not thread safe. If the BIO has been freed, + * we must not call the callback. The only way to be able to + * determine this is the reference count which is now invalid since + * the memory has been free()ed. + */ + if (b->references <= 0) abort(); + if (cb != NULL) /* && (b->references >= 1)) */ + i=(int)cb(b,BIO_CB_WRITE|BIO_CB_RETURN,in,inl, 0L,(long)i); return(i); } -int BIO_puts(b,in) -BIO *b; -char *in; +int BIO_puts(BIO *b, const char *in) { int i; + long (*cb)(); if ((b == NULL) || (b->method == NULL) || (b->method->bputs == NULL)) { @@ -207,30 +221,30 @@ char *in; return(-2); } - if ((b->callback != NULL) && - ((i=(int)b->callback(b,BIO_CB_PUTS,in,0,0L,1L)) <= 0)) + cb=b->callback; + + if ((cb != NULL) && + ((i=(int)cb(b,BIO_CB_PUTS,in,0,0L,1L)) <= 0)) return(i); if (!b->init) { - BIOerr(BIO_F_BIO_PUTS,BIO_R_UNINITALISED); + BIOerr(BIO_F_BIO_PUTS,BIO_R_UNINITIALIZED); return(-2); } i=b->method->bputs(b,in); - if (b->callback != NULL) - i=(int)b->callback(b,BIO_CB_PUTS|BIO_CB_RETURN,in,0, + if (cb != NULL) + i=(int)cb(b,BIO_CB_PUTS|BIO_CB_RETURN,in,0, 0L,(long)i); return(i); } -int BIO_gets(b,in,inl) -BIO *b; -char *in; -int inl; +int BIO_gets(BIO *b, char *in, int inl) { int i; + long (*cb)(); if ((b == NULL) || (b->method == NULL) || (b->method->bgets == NULL)) { @@ -238,29 +252,27 @@ int inl; return(-2); } - if ((b->callback != NULL) && - ((i=(int)b->callback(b,BIO_CB_GETS,in,inl,0L,1L)) <= 0)) + cb=b->callback; + + if ((cb != NULL) && + ((i=(int)cb(b,BIO_CB_GETS,in,inl,0L,1L)) <= 0)) return(i); if (!b->init) { - BIOerr(BIO_F_BIO_GETS,BIO_R_UNINITALISED); + BIOerr(BIO_F_BIO_GETS,BIO_R_UNINITIALIZED); return(-2); } i=b->method->bgets(b,in,inl); - if (b->callback != NULL) - i=(int)b->callback(b,BIO_CB_GETS|BIO_CB_RETURN,in,inl, + if (cb != NULL) + i=(int)cb(b,BIO_CB_GETS|BIO_CB_RETURN,in,inl, 0L,(long)i); return(i); } -long BIO_ctrl_int(b,cmd,larg,iarg) -BIO *b; -int cmd; -long larg; -int iarg; +long BIO_int_ctrl(BIO *b, int cmd, long larg, int iarg) { int i; @@ -268,13 +280,20 @@ int iarg; return(BIO_ctrl(b,cmd,larg,(char *)&i)); } -long BIO_ctrl(b,cmd,larg,parg) -BIO *b; -int cmd; -long larg; -char *parg; +char *BIO_ptr_ctrl(BIO *b, int cmd, long larg) + { + char *p=NULL; + + if (BIO_ctrl(b,cmd,larg,(char *)&p) <= 0) + return(NULL); + else + return(p); + } + +long BIO_ctrl(BIO *b, int cmd, long larg, void *parg) { long ret; + long (*cb)(); if (b == NULL) return(0); @@ -284,21 +303,36 @@ char *parg; return(-2); } - if ((b->callback != NULL) && - ((ret=b->callback(b,BIO_CB_CTRL,parg,cmd,larg,1L)) <= 0)) + cb=b->callback; + + if ((cb != NULL) && + ((ret=cb(b,BIO_CB_CTRL,parg,cmd,larg,1L)) <= 0)) return(ret); ret=b->method->ctrl(b,cmd,larg,parg); - if (b->callback != NULL) - ret=b->callback(b,BIO_CB_CTRL|BIO_CB_RETURN,parg,cmd, + if (cb != NULL) + ret=cb(b,BIO_CB_CTRL|BIO_CB_RETURN,parg,cmd, larg,ret); return(ret); } +/* It is unfortunate to duplicate in functions what the BIO_(w)pending macros + * do; but those macros have inappropriate return type, and for interfacing + * from other programming languages, C macros aren't much of a help anyway. */ +size_t BIO_ctrl_pending(BIO *bio) + { + return BIO_ctrl(bio, BIO_CTRL_PENDING, 0, NULL); + } + +size_t BIO_ctrl_wpending(BIO *bio) + { + return BIO_ctrl(bio, BIO_CTRL_WPENDING, 0, NULL); + } + + /* put the 'bio' on the end of b's list of operators */ -BIO *BIO_push(b,bio) -BIO *b,*bio; +BIO *BIO_push(BIO *b, BIO *bio) { BIO *lb; @@ -309,13 +343,13 @@ BIO *b,*bio; lb->next_bio=bio; if (bio != NULL) bio->prev_bio=lb; + /* called to do internal processing */ BIO_ctrl(b,BIO_CTRL_PUSH,0,NULL); return(b); } /* Remove the first and return the rest */ -BIO *BIO_pop(b) -BIO *b; +BIO *BIO_pop(BIO *b) { BIO *ret; @@ -333,9 +367,7 @@ BIO *b; return(ret); } -BIO *BIO_get_retry_BIO(bio,reason) -BIO *bio; -int *reason; +BIO *BIO_get_retry_BIO(BIO *bio, int *reason) { BIO *b,*last; @@ -351,15 +383,12 @@ int *reason; return(last); } -int BIO_get_retry_reason(bio) -BIO *bio; +int BIO_get_retry_reason(BIO *bio) { return(bio->retry_reason); } -BIO *BIO_find_type(bio,type) -BIO *bio; -int type; +BIO *BIO_find_type(BIO *bio, int type) { int mt,mask; @@ -381,8 +410,7 @@ int type; return(NULL); } -void BIO_free_all(bio) -BIO *bio; +void BIO_free_all(BIO *bio) { BIO *b; int ref; @@ -398,8 +426,7 @@ BIO *bio; } } -BIO *BIO_dup_chain(in) -BIO *in; +BIO *BIO_dup_chain(BIO *in) { BIO *ret=NULL,*eoc=NULL,*bio,*new; @@ -420,6 +447,11 @@ BIO *in; BIO_free(new); goto err; } + + /* copy app data */ + if (!CRYPTO_dup_ex_data(bio_meth,&new->ex_data,&bio->ex_data)) + goto err; + if (ret == NULL) { eoc=new; @@ -438,10 +470,27 @@ err: return(NULL); } -void BIO_copy_next_retry(b) -BIO *b; +void BIO_copy_next_retry(BIO *b) { BIO_set_flags(b,BIO_get_retry_flags(b->next_bio)); b->retry_reason=b->next_bio->retry_reason; } +int BIO_get_ex_new_index(long argl, char *argp, int (*new_func)(), + int (*dup_func)(), void (*free_func)()) + { + bio_meth_num++; + return(CRYPTO_get_ex_new_index(bio_meth_num-1,&bio_meth, + argl,argp,new_func,dup_func,free_func)); + } + +int BIO_set_ex_data(BIO *bio, int idx, char *data) + { + return(CRYPTO_set_ex_data(&(bio->ex_data),idx,data)); + } + +char *BIO_get_ex_data(BIO *bio, int idx) + { + return(CRYPTO_get_ex_data(&(bio->ex_data),idx)); + } +