diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/libcrypto/bio/bss_mem.c | 60 |
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 | ||
70 | struct bio_mem { | 70 | struct bio_mem { |
71 | BUF_MEM *buf; | 71 | BUF_MEM *buf; |
72 | size_t read_offset; | ||
72 | }; | 73 | }; |
73 | 74 | ||
75 | static size_t | ||
76 | bio_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 | |||
84 | static uint8_t * | ||
85 | bio_mem_read_ptr(struct bio_mem *bm) | ||
86 | { | ||
87 | return &bm->buf->data[bm->read_offset]; | ||
88 | } | ||
89 | |||
74 | static int mem_new(BIO *bio); | 90 | static int mem_new(BIO *bio); |
75 | static int mem_free(BIO *bio); | 91 | static int mem_free(BIO *bio); |
76 | static int mem_write(BIO *bio, const char *in, int in_len); | 92 | static 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++; |