diff options
Diffstat (limited to 'src/lib/libcrypto/bio/bss_mem.c')
-rw-r--r-- | src/lib/libcrypto/bio/bss_mem.c | 58 |
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 | ||
93 | BIO *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 | |||
92 | static int mem_new(BIO *bi) | 113 | static 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); |