Loading CHANGES +12 −0 Original line number Diff line number Diff line Loading @@ -4,6 +4,18 @@ Changes between 0.9.4 and 0.9.5 [xx XXX 1999] *) Add a new flag to memory BIOs, BIO_FLAG_MEM_RDONLY. This marks the BIO as "read only": it can't be written to and the buffer it points to will not be freed. Reading from a read only BIO is much more efficient than a normal memory BIO. This was added because there are several times when an area of memory needs to be read from a BIO. The previous method was to create a memory BIO and write the data to it, this results in two copies of the data and an O(n^2) reading algorithm. There is a new function BIO_new_mem_buf() which creates a read only memory BIO from an area of memory. Also modified the PKCS#7 routines to use read only memory BIOSs. [Steve Henson] *) Bugfix: ssl23_get_client_hello did not work properly when called in state SSL23_ST_SR_CLNT_HELLO_B, i.e. when the first 7 bytes of a SSLv2-compatible client hello for SSLv3 or TLSv1 could be read, Loading crypto/bio/bio.h +8 −0 Original line number Diff line number Diff line Loading @@ -147,6 +147,11 @@ extern "C" { #define BIO_FLAGS_BASE64_NO_NL 0x100 /* This is used with memory BIOs: it means we shouldn't free up or change the * data in any way. */ #define BIO_FLAGS_MEM_RDONLY 0x200 #define BIO_set_flags(b,f) ((b)->flags|=(f)) #define BIO_get_flags(b) ((b)->flags) #define BIO_set_retry_special(b) \ Loading Loading @@ -526,6 +531,7 @@ long _far _loadds BIO_debug_callback(BIO *bio,int cmd,const char *argp,int argi, #endif BIO_METHOD *BIO_s_mem(void); BIO *BIO_new_mem_buf(void *buf, int len); BIO_METHOD *BIO_s_socket(void); BIO_METHOD *BIO_s_connect(void); BIO_METHOD *BIO_s_accept(void); Loading Loading @@ -604,6 +610,7 @@ int BIO_printf(BIO *bio, ...); #define BIO_F_BIO_MAKE_PAIR 121 #define BIO_F_BIO_NEW 108 #define BIO_F_BIO_NEW_FILE 109 #define BIO_F_BIO_NEW_MEM_BUF 126 #define BIO_F_BIO_NREAD 123 #define BIO_F_BIO_NREAD0 124 #define BIO_F_BIO_NWRITE 125 Loading Loading @@ -645,6 +652,7 @@ int BIO_printf(BIO *bio, ...); #define BIO_R_UNABLE_TO_LISTEN_SOCKET 119 #define BIO_R_UNINITIALIZED 120 #define BIO_R_UNSUPPORTED_METHOD 121 #define BIO_R_WRITE_TO_READ_ONLY_BIO 126 #define BIO_R_WSASTARTUP 122 #ifdef __cplusplus Loading crypto/bio/bio_err.c +2 −0 Original line number Diff line number Diff line Loading @@ -77,6 +77,7 @@ static ERR_STRING_DATA BIO_str_functs[]= {ERR_PACK(0,BIO_F_BIO_MAKE_PAIR,0), "BIO_MAKE_PAIR"}, {ERR_PACK(0,BIO_F_BIO_NEW,0), "BIO_new"}, {ERR_PACK(0,BIO_F_BIO_NEW_FILE,0), "BIO_new_file"}, {ERR_PACK(0,BIO_F_BIO_NEW_MEM_BUF,0), "BIO_new_mem_buf"}, {ERR_PACK(0,BIO_F_BIO_NREAD,0), "BIO_nread"}, {ERR_PACK(0,BIO_F_BIO_NREAD0,0), "BIO_nread0"}, {ERR_PACK(0,BIO_F_BIO_NWRITE,0), "BIO_nwrite"}, Loading Loading @@ -121,6 +122,7 @@ static ERR_STRING_DATA BIO_str_reasons[]= {BIO_R_UNABLE_TO_LISTEN_SOCKET ,"unable to listen socket"}, {BIO_R_UNINITIALIZED ,"uninitialized"}, {BIO_R_UNSUPPORTED_METHOD ,"unsupported method"}, {BIO_R_WRITE_TO_READ_ONLY_BIO ,"write to read only bio"}, {BIO_R_WSASTARTUP ,"wsastartup"}, {0,NULL} }; Loading crypto/bio/bss_mem.c +46 −11 Original line number Diff line number Diff line Loading @@ -89,6 +89,26 @@ BIO_METHOD *BIO_s_mem(void) return(&mem_method); } 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; Loading @@ -109,7 +129,10 @@ static int mem_free(BIO *a) { 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; } } Loading @@ -126,17 +149,18 @@ static int mem_read(BIO *b, char *out, 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); */ if(b->flags & BIO_FLAGS_MEM_RDONLY) bm->data += ret; else { from=(char *)&(bm->data[ret]); to=(char *)&(bm->data[0]); for (i=0; i<bm->length; i++) to[i]=from[i]; } else if (bm->length == 0) } else if (bm->length == 0) { if (b->num != 0) BIO_set_retry_read(b); Loading @@ -158,6 +182,11 @@ static int mem_write(BIO *b, char *in, 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)) Loading @@ -178,9 +207,15 @@ static long mem_ctrl(BIO *b, int cmd, long num, char *ptr) switch (cmd) { case BIO_CTRL_RESET: if (bm->data != NULL) if (bm->data != NULL) { /* For read only case reset to the start again */ if(b->flags & BIO_FLAGS_MEM_RDONLY) bm->data -= bm->max - bm->length; else { memset(bm->data,0,bm->max); bm->length=0; } } break; case BIO_CTRL_EOF: ret=(long)(bm->length == 0); Loading crypto/pkcs7/pk7_doit.c +27 −17 Original line number Diff line number Diff line Loading @@ -216,27 +216,19 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) btmp=NULL; } if (bio == NULL) /* ??????????? */ { if (bio == NULL) { if (p7->detached) bio=BIO_new(BIO_s_null()); else { bio=BIO_new(BIO_s_mem()); /* We need to set this so that when we have read all * the data, the encrypt BIO, if present, will read * EOF and encode the last few bytes */ BIO_set_mem_eof_return(bio,0); else { if (PKCS7_type_is_signed(p7) && PKCS7_type_is_data(p7->d.sign->contents)) { PKCS7_type_is_data(p7->d.sign->contents)) { ASN1_OCTET_STRING *os; os=p7->d.sign->contents->d.data; if (os->length > 0) BIO_write(bio,(char *)os->data, os->length); if (os->length > 0) bio = BIO_new_mem_buf(os->data, os->length); } else { bio=BIO_new(BIO_s_mem()); BIO_set_mem_eof_return(bio,0); } } } Loading Loading @@ -430,6 +422,7 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) } else { #if 0 bio=BIO_new(BIO_s_mem()); /* We need to set this so that when we have read all * the data, the encrypt BIO, if present, will read Loading @@ -438,6 +431,14 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) if (data_body->length > 0) BIO_write(bio,(char *)data_body->data,data_body->length); #else if (data_body->length > 0) bio = BIO_new_mem_buf(data_body->data,data_body->length); else { bio=BIO_new(BIO_s_mem()); BIO_set_mem_eof_return(bio,0); } #endif } BIO_push(out,bio); bio=NULL; Loading Loading @@ -611,8 +612,17 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) goto err; } BIO_get_mem_ptr(btmp,&buf_mem); /* Mark the BIO read only then we can use its copy of the data * instead of making an extra copy. */ BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY); BIO_set_mem_eof_return(btmp, 0); os->data = (unsigned char *)buf_mem->data; os->length = buf_mem->length; #if 0 ASN1_OCTET_STRING_set(os, (unsigned char *)buf_mem->data,buf_mem->length); #endif } if (pp != NULL) Free(pp); pp=NULL; Loading Loading
CHANGES +12 −0 Original line number Diff line number Diff line Loading @@ -4,6 +4,18 @@ Changes between 0.9.4 and 0.9.5 [xx XXX 1999] *) Add a new flag to memory BIOs, BIO_FLAG_MEM_RDONLY. This marks the BIO as "read only": it can't be written to and the buffer it points to will not be freed. Reading from a read only BIO is much more efficient than a normal memory BIO. This was added because there are several times when an area of memory needs to be read from a BIO. The previous method was to create a memory BIO and write the data to it, this results in two copies of the data and an O(n^2) reading algorithm. There is a new function BIO_new_mem_buf() which creates a read only memory BIO from an area of memory. Also modified the PKCS#7 routines to use read only memory BIOSs. [Steve Henson] *) Bugfix: ssl23_get_client_hello did not work properly when called in state SSL23_ST_SR_CLNT_HELLO_B, i.e. when the first 7 bytes of a SSLv2-compatible client hello for SSLv3 or TLSv1 could be read, Loading
crypto/bio/bio.h +8 −0 Original line number Diff line number Diff line Loading @@ -147,6 +147,11 @@ extern "C" { #define BIO_FLAGS_BASE64_NO_NL 0x100 /* This is used with memory BIOs: it means we shouldn't free up or change the * data in any way. */ #define BIO_FLAGS_MEM_RDONLY 0x200 #define BIO_set_flags(b,f) ((b)->flags|=(f)) #define BIO_get_flags(b) ((b)->flags) #define BIO_set_retry_special(b) \ Loading Loading @@ -526,6 +531,7 @@ long _far _loadds BIO_debug_callback(BIO *bio,int cmd,const char *argp,int argi, #endif BIO_METHOD *BIO_s_mem(void); BIO *BIO_new_mem_buf(void *buf, int len); BIO_METHOD *BIO_s_socket(void); BIO_METHOD *BIO_s_connect(void); BIO_METHOD *BIO_s_accept(void); Loading Loading @@ -604,6 +610,7 @@ int BIO_printf(BIO *bio, ...); #define BIO_F_BIO_MAKE_PAIR 121 #define BIO_F_BIO_NEW 108 #define BIO_F_BIO_NEW_FILE 109 #define BIO_F_BIO_NEW_MEM_BUF 126 #define BIO_F_BIO_NREAD 123 #define BIO_F_BIO_NREAD0 124 #define BIO_F_BIO_NWRITE 125 Loading Loading @@ -645,6 +652,7 @@ int BIO_printf(BIO *bio, ...); #define BIO_R_UNABLE_TO_LISTEN_SOCKET 119 #define BIO_R_UNINITIALIZED 120 #define BIO_R_UNSUPPORTED_METHOD 121 #define BIO_R_WRITE_TO_READ_ONLY_BIO 126 #define BIO_R_WSASTARTUP 122 #ifdef __cplusplus Loading
crypto/bio/bio_err.c +2 −0 Original line number Diff line number Diff line Loading @@ -77,6 +77,7 @@ static ERR_STRING_DATA BIO_str_functs[]= {ERR_PACK(0,BIO_F_BIO_MAKE_PAIR,0), "BIO_MAKE_PAIR"}, {ERR_PACK(0,BIO_F_BIO_NEW,0), "BIO_new"}, {ERR_PACK(0,BIO_F_BIO_NEW_FILE,0), "BIO_new_file"}, {ERR_PACK(0,BIO_F_BIO_NEW_MEM_BUF,0), "BIO_new_mem_buf"}, {ERR_PACK(0,BIO_F_BIO_NREAD,0), "BIO_nread"}, {ERR_PACK(0,BIO_F_BIO_NREAD0,0), "BIO_nread0"}, {ERR_PACK(0,BIO_F_BIO_NWRITE,0), "BIO_nwrite"}, Loading Loading @@ -121,6 +122,7 @@ static ERR_STRING_DATA BIO_str_reasons[]= {BIO_R_UNABLE_TO_LISTEN_SOCKET ,"unable to listen socket"}, {BIO_R_UNINITIALIZED ,"uninitialized"}, {BIO_R_UNSUPPORTED_METHOD ,"unsupported method"}, {BIO_R_WRITE_TO_READ_ONLY_BIO ,"write to read only bio"}, {BIO_R_WSASTARTUP ,"wsastartup"}, {0,NULL} }; Loading
crypto/bio/bss_mem.c +46 −11 Original line number Diff line number Diff line Loading @@ -89,6 +89,26 @@ BIO_METHOD *BIO_s_mem(void) return(&mem_method); } 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; Loading @@ -109,7 +129,10 @@ static int mem_free(BIO *a) { 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; } } Loading @@ -126,17 +149,18 @@ static int mem_read(BIO *b, char *out, 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); */ if(b->flags & BIO_FLAGS_MEM_RDONLY) bm->data += ret; else { from=(char *)&(bm->data[ret]); to=(char *)&(bm->data[0]); for (i=0; i<bm->length; i++) to[i]=from[i]; } else if (bm->length == 0) } else if (bm->length == 0) { if (b->num != 0) BIO_set_retry_read(b); Loading @@ -158,6 +182,11 @@ static int mem_write(BIO *b, char *in, 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)) Loading @@ -178,9 +207,15 @@ static long mem_ctrl(BIO *b, int cmd, long num, char *ptr) switch (cmd) { case BIO_CTRL_RESET: if (bm->data != NULL) if (bm->data != NULL) { /* For read only case reset to the start again */ if(b->flags & BIO_FLAGS_MEM_RDONLY) bm->data -= bm->max - bm->length; else { memset(bm->data,0,bm->max); bm->length=0; } } break; case BIO_CTRL_EOF: ret=(long)(bm->length == 0); Loading
crypto/pkcs7/pk7_doit.c +27 −17 Original line number Diff line number Diff line Loading @@ -216,27 +216,19 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) btmp=NULL; } if (bio == NULL) /* ??????????? */ { if (bio == NULL) { if (p7->detached) bio=BIO_new(BIO_s_null()); else { bio=BIO_new(BIO_s_mem()); /* We need to set this so that when we have read all * the data, the encrypt BIO, if present, will read * EOF and encode the last few bytes */ BIO_set_mem_eof_return(bio,0); else { if (PKCS7_type_is_signed(p7) && PKCS7_type_is_data(p7->d.sign->contents)) { PKCS7_type_is_data(p7->d.sign->contents)) { ASN1_OCTET_STRING *os; os=p7->d.sign->contents->d.data; if (os->length > 0) BIO_write(bio,(char *)os->data, os->length); if (os->length > 0) bio = BIO_new_mem_buf(os->data, os->length); } else { bio=BIO_new(BIO_s_mem()); BIO_set_mem_eof_return(bio,0); } } } Loading Loading @@ -430,6 +422,7 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) } else { #if 0 bio=BIO_new(BIO_s_mem()); /* We need to set this so that when we have read all * the data, the encrypt BIO, if present, will read Loading @@ -438,6 +431,14 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) if (data_body->length > 0) BIO_write(bio,(char *)data_body->data,data_body->length); #else if (data_body->length > 0) bio = BIO_new_mem_buf(data_body->data,data_body->length); else { bio=BIO_new(BIO_s_mem()); BIO_set_mem_eof_return(bio,0); } #endif } BIO_push(out,bio); bio=NULL; Loading Loading @@ -611,8 +612,17 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) goto err; } BIO_get_mem_ptr(btmp,&buf_mem); /* Mark the BIO read only then we can use its copy of the data * instead of making an extra copy. */ BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY); BIO_set_mem_eof_return(btmp, 0); os->data = (unsigned char *)buf_mem->data; os->length = buf_mem->length; #if 0 ASN1_OCTET_STRING_set(os, (unsigned char *)buf_mem->data,buf_mem->length); #endif } if (pp != NULL) Free(pp); pp=NULL; Loading