summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/libcrypto/bio/bss_mem.c60
1 files changed, 38 insertions, 22 deletions
diff --git a/src/lib/libcrypto/bio/bss_mem.c b/src/lib/libcrypto/bio/bss_mem.c
index 6100a1861e..2d03083235 100644
--- a/src/lib/libcrypto/bio/bss_mem.c
+++ b/src/lib/libcrypto/bio/bss_mem.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: bss_mem.c,v 1.20 2022/02/19 08:11:16 jsing Exp $ */ 1/* $OpenBSD: bss_mem.c,v 1.21 2022/02/19 15:59:12 jsing Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
@@ -69,8 +69,24 @@
69 69
70struct bio_mem { 70struct bio_mem {
71 BUF_MEM *buf; 71 BUF_MEM *buf;
72 size_t read_offset;
72}; 73};
73 74
75static size_t
76bio_mem_pending(struct bio_mem *bm)
77{
78 if (bm->read_offset > bm->buf->length)
79 return 0;
80
81 return bm->buf->length - bm->read_offset;
82}
83
84static uint8_t *
85bio_mem_read_ptr(struct bio_mem *bm)
86{
87 return &bm->buf->data[bm->read_offset];
88}
89
74static int mem_new(BIO *bio); 90static int mem_new(BIO *bio);
75static int mem_free(BIO *bio); 91static int mem_free(BIO *bio);
76static int mem_write(BIO *bio, const char *in, int in_len); 92static int mem_write(BIO *bio, const char *in, int in_len);
@@ -185,8 +201,8 @@ mem_read(BIO *bio, char *out, int out_len)
185 if (out == NULL || out_len <= 0) 201 if (out == NULL || out_len <= 0)
186 return 0; 202 return 0;
187 203
188 if ((size_t)out_len > bm->buf->length) 204 if ((size_t)out_len > bio_mem_pending(bm))
189 out_len = bm->buf->length; 205 out_len = bio_mem_pending(bm);
190 206
191 if (out_len == 0) { 207 if (out_len == 0) {
192 if (bio->num != 0) 208 if (bio->num != 0)
@@ -194,14 +210,9 @@ mem_read(BIO *bio, char *out, int out_len)
194 return bio->num; 210 return bio->num;
195 } 211 }
196 212
197 memcpy(out, bm->buf->data, out_len); 213 memcpy(out, bio_mem_read_ptr(bm), out_len);
198 bm->buf->length -= out_len; 214 bm->read_offset += out_len;
199 if (bio->flags & BIO_FLAGS_MEM_RDONLY) { 215
200 bm->buf->data += out_len;
201 } else {
202 memmove(&(bm->buf->data[0]), &(bm->buf->data[out_len]),
203 bm->buf->length);
204 }
205 return out_len; 216 return out_len;
206} 217}
207 218
@@ -221,6 +232,13 @@ mem_write(BIO *bio, const char *in, int in_len)
221 return -1; 232 return -1;
222 } 233 }
223 234
235 if (bm->read_offset > 4096) {
236 memmove(bm->buf->data, bio_mem_read_ptr(bm),
237 bio_mem_pending(bm));
238 bm->buf->length = bio_mem_pending(bm);
239 bm->read_offset = 0;
240 }
241
224 /* 242 /*
225 * Check for overflow and ensure we do not exceed an int, otherwise we 243 * Check for overflow and ensure we do not exceed an int, otherwise we
226 * cannot tell if BUF_MEM_grow_clean() succeeded. 244 * cannot tell if BUF_MEM_grow_clean() succeeded.
@@ -247,18 +265,15 @@ mem_ctrl(BIO *bio, int cmd, long num, void *ptr)
247 switch (cmd) { 265 switch (cmd) {
248 case BIO_CTRL_RESET: 266 case BIO_CTRL_RESET:
249 if (bm->buf->data != NULL) { 267 if (bm->buf->data != NULL) {
250 /* For read only case reset to the start again */ 268 if (!(bio->flags & BIO_FLAGS_MEM_RDONLY)) {
251 if (bio->flags & BIO_FLAGS_MEM_RDONLY) {
252 bm->buf->data -= bm->buf->max - bm->buf->length;
253 bm->buf->length = bm->buf->max;
254 } else {
255 memset(bm->buf->data, 0, bm->buf->max); 269 memset(bm->buf->data, 0, bm->buf->max);
256 bm->buf->length = 0; 270 bm->buf->length = 0;
257 } 271 }
272 bm->read_offset = 0;
258 } 273 }
259 break; 274 break;
260 case BIO_CTRL_EOF: 275 case BIO_CTRL_EOF:
261 ret = (long)(bm->buf->length == 0); 276 ret = (long)(bio_mem_pending(bm) == 0);
262 break; 277 break;
263 case BIO_C_SET_BUF_MEM_EOF_RETURN: 278 case BIO_C_SET_BUF_MEM_EOF_RETURN:
264 bio->num = (int)num; 279 bio->num = (int)num;
@@ -266,14 +281,15 @@ mem_ctrl(BIO *bio, int cmd, long num, void *ptr)
266 case BIO_CTRL_INFO: 281 case BIO_CTRL_INFO:
267 if (ptr != NULL) { 282 if (ptr != NULL) {
268 pptr = (void **)ptr; 283 pptr = (void **)ptr;
269 *pptr = bm->buf->data; 284 *pptr = bio_mem_read_ptr(bm);
270 } 285 }
271 ret = (long)bm->buf->length; 286 ret = (long)bio_mem_pending(bm);
272 break; 287 break;
273 case BIO_C_SET_BUF_MEM: 288 case BIO_C_SET_BUF_MEM:
274 BUF_MEM_free(bm->buf); 289 BUF_MEM_free(bm->buf);
275 bio->shutdown = (int)num; 290 bio->shutdown = (int)num;
276 bm->buf = ptr; 291 bm->buf = ptr;
292 bm->read_offset = 0;
277 break; 293 break;
278 case BIO_C_GET_BUF_MEM_PTR: 294 case BIO_C_GET_BUF_MEM_PTR:
279 if (ptr != NULL) { 295 if (ptr != NULL) {
@@ -291,7 +307,7 @@ mem_ctrl(BIO *bio, int cmd, long num, void *ptr)
291 ret = 0L; 307 ret = 0L;
292 break; 308 break;
293 case BIO_CTRL_PENDING: 309 case BIO_CTRL_PENDING:
294 ret = (long)bm->buf->length; 310 ret = (long)bio_mem_pending(bm);
295 break; 311 break;
296 case BIO_CTRL_DUP: 312 case BIO_CTRL_DUP:
297 case BIO_CTRL_FLUSH: 313 case BIO_CTRL_FLUSH:
@@ -316,7 +332,7 @@ mem_gets(BIO *bio, char *out, int out_len)
316 332
317 BIO_clear_retry_flags(bio); 333 BIO_clear_retry_flags(bio);
318 334
319 out_max = bm->buf->length; 335 out_max = bio_mem_pending(bm);
320 if (out_len - 1 < out_max) 336 if (out_len - 1 < out_max)
321 out_max = out_len - 1; 337 out_max = out_len - 1;
322 if (out_max <= 0) { 338 if (out_max <= 0) {
@@ -324,7 +340,7 @@ mem_gets(BIO *bio, char *out, int out_len)
324 return 0; 340 return 0;
325 } 341 }
326 342
327 p = bm->buf->data; 343 p = bio_mem_read_ptr(bm);
328 for (i = 0; i < out_max; i++) { 344 for (i = 0; i < out_max; i++) {
329 if (p[i] == '\n') { 345 if (p[i] == '\n') {
330 i++; 346 i++;