X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=crypto%2Fbio%2Fbss_mem.c;h=d4d956c619ab121fa5e7f770f0cabc2522e2d928;hp=40c4e39f025ef1afa056e63136b13d716dff2338;hb=ccc265eaa7a0af0e52aab6961ac3ddd9e5a22156;hpb=78414a6a897db42c9bcf06aa21c705811ab33921 diff --git a/crypto/bio/bss_mem.c b/crypto/bio/bss_mem.c index 40c4e39f02..d4d956c619 100644 --- a/crypto/bio/bss_mem.c +++ b/crypto/bio/bss_mem.c @@ -59,26 +59,15 @@ #include #include #include "cryptlib.h" -#include "bio.h" +#include -#ifndef NOPROTO -static int mem_write(BIO *h,char *buf,int num); -static int mem_read(BIO *h,char *buf,int size); -static int mem_puts(BIO *h,char *str); -static int mem_gets(BIO *h,char *str,int size); -static long mem_ctrl(BIO *h,int cmd,long arg1,char *arg2); +static int mem_write(BIO *h, const char *buf, int num); +static int mem_read(BIO *h, char *buf, int size); +static int mem_puts(BIO *h, const char *str); +static int mem_gets(BIO *h, char *str, int size); +static long mem_ctrl(BIO *h, int cmd, long arg1, void *arg2); static int mem_new(BIO *h); static int mem_free(BIO *data); -#else -static int mem_write(); -static int mem_read(); -static int mem_puts(); -static int mem_gets(); -static long mem_ctrl(); -static int mem_new(); -static int mem_free(); -#endif - static BIO_METHOD mem_method= { BIO_TYPE_MEM, @@ -90,15 +79,38 @@ static BIO_METHOD mem_method= mem_ctrl, mem_new, mem_free, + NULL, }; -BIO_METHOD *BIO_s_mem() +/* bio->num is used to hold the value to return on 'empty', if it is + * 0, should_retry is not set */ + +BIO_METHOD *BIO_s_mem(void) { return(&mem_method); } -static int mem_new(bi) -BIO *bi; +BIO *BIO_new_mem_buf(void *buf, int len) +{ + BIO *ret; + BUF_MEM *b; + if (!buf) { + BIOerr(BIO_F_BIO_NEW_MEM_BUF,BIO_R_NULL_PARAMETER); + return NULL; + } + if(len == -1) len = strlen(buf); + if(!(ret = BIO_new(BIO_s_mem())) ) return NULL; + b = (BUF_MEM *)ret->ptr; + b->data = buf; + b->length = len; + b->max = len; + ret->flags |= BIO_FLAGS_MEM_RDONLY; + /* Since this is static data retrying wont help */ + ret->num = 0; + return ret; +} + +static int mem_new(BIO *bi) { BUF_MEM *b; @@ -106,30 +118,29 @@ BIO *bi; return(0); bi->shutdown=1; bi->init=1; - bi->num=0; + bi->num= -1; bi->ptr=(char *)b; return(1); } -static int mem_free(a) -BIO *a; +static int mem_free(BIO *a) { if (a == NULL) return(0); if (a->shutdown) { if ((a->init) && (a->ptr != NULL)) { - BUF_MEM_free((BUF_MEM *)a->ptr); + BUF_MEM *b; + b = (BUF_MEM *)a->ptr; + if(a->flags & BIO_FLAGS_MEM_RDONLY) b->data = NULL; + BUF_MEM_free(b); a->ptr=NULL; } } return(1); } -static int mem_read(b,out,outl) -BIO *b; -char *out; -int outl; +static int mem_read(BIO *b, char *out, int outl) { int ret= -1; BUF_MEM *bm; @@ -139,28 +150,29 @@ int outl; bm=(BUF_MEM *)b->ptr; BIO_clear_retry_flags(b); ret=(outl > bm->length)?bm->length:outl; - if ((out != NULL) && (ret > 0)) - { + if ((out != NULL) && (ret > 0)) { memcpy(out,bm->data,ret); bm->length-=ret; /* memmove(&(bm->data[0]),&(bm->data[ret]), bm->length); */ - from=(char *)&(bm->data[ret]); - to=(char *)&(bm->data[0]); - for (i=0; ilength; i++) - to[i]=from[i]; + if(b->flags & BIO_FLAGS_MEM_RDONLY) bm->data += ret; + else { + from=(char *)&(bm->data[ret]); + to=(char *)&(bm->data[0]); + for (i=0; ilength; i++) + to[i]=from[i]; } - else if (bm->length == 0) + } else if (bm->length == 0) { - BIO_set_retry_read(b); - ret= -1; + if (b->num != 0) + BIO_set_retry_read(b); + ret= b->num; + if(ret < 0) + BIOerr(BIO_F_MEM_READ,BIO_R_EOF_ON_MEMORY_BIO); } return(ret); } -static int mem_write(b,in,inl) -BIO *b; -char *in; -int inl; +static int mem_write(BIO *b, const char *in, int inl) { int ret= -1; int blen; @@ -173,6 +185,11 @@ int inl; goto end; } + if(b->flags & BIO_FLAGS_MEM_RDONLY) { + BIOerr(BIO_F_MEM_WRITE,BIO_R_WRITE_TO_READ_ONLY_BIO); + goto end; + } + BIO_clear_retry_flags(b); blen=bm->length; if (BUF_MEM_grow(bm,blen+inl) != (blen+inl)) @@ -183,11 +200,7 @@ end: return(ret); } -static long mem_ctrl(b,cmd,num,ptr) -BIO *b; -int cmd; -long num; -char *ptr; +static long mem_ctrl(BIO *b, int cmd, long num, void *ptr) { long ret=1; char **pptr; @@ -198,12 +211,26 @@ char *ptr; { case BIO_CTRL_RESET: if (bm->data != NULL) - memset(bm->data,0,bm->max); - bm->length=0; + { + /* For read only case reset to the start again */ + if(b->flags & BIO_FLAGS_MEM_RDONLY) + { + bm->data -= bm->max - bm->length; + bm->length = bm->max; + } + else + { + memset(bm->data,0,bm->max); + bm->length=0; + } + } break; case BIO_CTRL_EOF: ret=(long)(bm->length == 0); break; + case BIO_C_SET_BUF_MEM_EOF_RETURN: + b->num=(int)num; + break; case BIO_CTRL_INFO: ret=(long)bm->length; if (ptr != NULL) @@ -250,10 +277,7 @@ char *ptr; return(ret); } -static int mem_gets(bp,buf,size) -BIO *bp; -char *buf; -int size; +static int mem_gets(BIO *bp, char *buf, int size) { int i,j; int ret= -1; @@ -283,9 +307,7 @@ int size; return(ret); } -static int mem_puts(bp,str) -BIO *bp; -char *str; +static int mem_puts(BIO *bp, const char *str) { int n,ret;