summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/bio/bss_mem.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/bio/bss_mem.c')
-rw-r--r--src/lib/libcrypto/bio/bss_mem.c58
1 files changed, 47 insertions, 11 deletions
diff --git a/src/lib/libcrypto/bio/bss_mem.c b/src/lib/libcrypto/bio/bss_mem.c
index 7e749a503e..41eab92415 100644
--- a/src/lib/libcrypto/bio/bss_mem.c
+++ b/src/lib/libcrypto/bio/bss_mem.c
@@ -79,6 +79,7 @@ static BIO_METHOD mem_method=
79 mem_ctrl, 79 mem_ctrl,
80 mem_new, 80 mem_new,
81 mem_free, 81 mem_free,
82 NULL,
82 }; 83 };
83 84
84/* bio->num is used to hold the value to return on 'empty', if it is 85/* bio->num is used to hold the value to return on 'empty', if it is
@@ -89,6 +90,26 @@ BIO_METHOD *BIO_s_mem(void)
89 return(&mem_method); 90 return(&mem_method);
90 } 91 }
91 92
93BIO *BIO_new_mem_buf(void *buf, int len)
94{
95 BIO *ret;
96 BUF_MEM *b;
97 if (!buf) {
98 BIOerr(BIO_F_BIO_NEW_MEM_BUF,BIO_R_NULL_PARAMETER);
99 return NULL;
100 }
101 if(len == -1) len = strlen(buf);
102 if(!(ret = BIO_new(BIO_s_mem())) ) return NULL;
103 b = (BUF_MEM *)ret->ptr;
104 b->data = buf;
105 b->length = len;
106 b->max = len;
107 ret->flags |= BIO_FLAGS_MEM_RDONLY;
108 /* Since this is static data retrying wont help */
109 ret->num = 0;
110 return ret;
111}
112
92static int mem_new(BIO *bi) 113static int mem_new(BIO *bi)
93 { 114 {
94 BUF_MEM *b; 115 BUF_MEM *b;
@@ -109,7 +130,10 @@ static int mem_free(BIO *a)
109 { 130 {
110 if ((a->init) && (a->ptr != NULL)) 131 if ((a->init) && (a->ptr != NULL))
111 { 132 {
112 BUF_MEM_free((BUF_MEM *)a->ptr); 133 BUF_MEM *b;
134 b = (BUF_MEM *)a->ptr;
135 if(a->flags & BIO_FLAGS_MEM_RDONLY) b->data = NULL;
136 BUF_MEM_free(b);
113 a->ptr=NULL; 137 a->ptr=NULL;
114 } 138 }
115 } 139 }
@@ -126,17 +150,18 @@ static int mem_read(BIO *b, char *out, int outl)
126 bm=(BUF_MEM *)b->ptr; 150 bm=(BUF_MEM *)b->ptr;
127 BIO_clear_retry_flags(b); 151 BIO_clear_retry_flags(b);
128 ret=(outl > bm->length)?bm->length:outl; 152 ret=(outl > bm->length)?bm->length:outl;
129 if ((out != NULL) && (ret > 0)) 153 if ((out != NULL) && (ret > 0)) {
130 {
131 memcpy(out,bm->data,ret); 154 memcpy(out,bm->data,ret);
132 bm->length-=ret; 155 bm->length-=ret;
133 /* memmove(&(bm->data[0]),&(bm->data[ret]), bm->length); */ 156 /* memmove(&(bm->data[0]),&(bm->data[ret]), bm->length); */
134 from=(char *)&(bm->data[ret]); 157 if(b->flags & BIO_FLAGS_MEM_RDONLY) bm->data += ret;
135 to=(char *)&(bm->data[0]); 158 else {
136 for (i=0; i<bm->length; i++) 159 from=(char *)&(bm->data[ret]);
137 to[i]=from[i]; 160 to=(char *)&(bm->data[0]);
161 for (i=0; i<bm->length; i++)
162 to[i]=from[i];
138 } 163 }
139 else if (bm->length == 0) 164 } else if (bm->length == 0)
140 { 165 {
141 if (b->num != 0) 166 if (b->num != 0)
142 BIO_set_retry_read(b); 167 BIO_set_retry_read(b);
@@ -158,6 +183,11 @@ static int mem_write(BIO *b, char *in, int inl)
158 goto end; 183 goto end;
159 } 184 }
160 185
186 if(b->flags & BIO_FLAGS_MEM_RDONLY) {
187 BIOerr(BIO_F_MEM_WRITE,BIO_R_WRITE_TO_READ_ONLY_BIO);
188 goto end;
189 }
190
161 BIO_clear_retry_flags(b); 191 BIO_clear_retry_flags(b);
162 blen=bm->length; 192 blen=bm->length;
163 if (BUF_MEM_grow(bm,blen+inl) != (blen+inl)) 193 if (BUF_MEM_grow(bm,blen+inl) != (blen+inl))
@@ -178,9 +208,15 @@ static long mem_ctrl(BIO *b, int cmd, long num, char *ptr)
178 switch (cmd) 208 switch (cmd)
179 { 209 {
180 case BIO_CTRL_RESET: 210 case BIO_CTRL_RESET:
181 if (bm->data != NULL) 211 if (bm->data != NULL) {
182 memset(bm->data,0,bm->max); 212 /* For read only case reset to the start again */
183 bm->length=0; 213 if(b->flags & BIO_FLAGS_MEM_RDONLY)
214 bm->data -= bm->max - bm->length;
215 else {
216 memset(bm->data,0,bm->max);
217 bm->length=0;
218 }
219 }
184 break; 220 break;
185 case BIO_CTRL_EOF: 221 case BIO_CTRL_EOF:
186 ret=(long)(bm->length == 0); 222 ret=(long)(bm->length == 0);