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++; |
