diff options
Diffstat (limited to 'freebsd/crypto/openssl/crypto/bio/bss_mem.c')
-rw-r--r-- | freebsd/crypto/openssl/crypto/bio/bss_mem.c | 65 |
1 files changed, 42 insertions, 23 deletions
diff --git a/freebsd/crypto/openssl/crypto/bio/bss_mem.c b/freebsd/crypto/openssl/crypto/bio/bss_mem.c index 1aa581ad..be61400b 100644 --- a/freebsd/crypto/openssl/crypto/bio/bss_mem.c +++ b/freebsd/crypto/openssl/crypto/bio/bss_mem.c @@ -1,7 +1,7 @@ #include <machine/rtems-bsd-user-space.h> /* - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -22,7 +22,7 @@ static long mem_ctrl(BIO *h, int cmd, long arg1, void *arg2); static int mem_new(BIO *h); static int secmem_new(BIO *h); static int mem_free(BIO *data); -static int mem_buf_free(BIO *data, int free_all); +static int mem_buf_free(BIO *data); static int mem_buf_sync(BIO *h); static const BIO_METHOD mem_method = { @@ -59,7 +59,12 @@ static const BIO_METHOD secmem_method = { NULL, /* mem_callback_ctrl */ }; -/* BIO memory stores buffer and read pointer */ +/* + * BIO memory stores buffer and read pointer + * however the roles are different for read only BIOs. + * In that case the readp just stores the original state + * to be used for reset. + */ typedef struct bio_buf_mem_st { struct buf_mem_st *buf; /* allocated buffer */ struct buf_mem_st *readp; /* read pointer */ @@ -142,10 +147,20 @@ static int secmem_new(BIO *bi) static int mem_free(BIO *a) { - return mem_buf_free(a, 1); + BIO_BUF_MEM *bb; + + if (a == NULL) + return 0; + + bb = (BIO_BUF_MEM *)a->ptr; + if (!mem_buf_free(a)) + return 0; + OPENSSL_free(bb->readp); + OPENSSL_free(bb); + return 1; } -static int mem_buf_free(BIO *a, int free_all) +static int mem_buf_free(BIO *a) { if (a == NULL) return 0; @@ -157,11 +172,6 @@ static int mem_buf_free(BIO *a, int free_all) if (a->flags & BIO_FLAGS_MEM_RDONLY) b->data = NULL; BUF_MEM_free(b); - if (free_all) { - OPENSSL_free(bb->readp); - OPENSSL_free(bb); - } - a->ptr = NULL; } return 1; } @@ -189,11 +199,14 @@ static int mem_read(BIO *b, char *out, int outl) BIO_BUF_MEM *bbm = (BIO_BUF_MEM *)b->ptr; BUF_MEM *bm = bbm->readp; + if (b->flags & BIO_FLAGS_MEM_RDONLY) + bm = bbm->buf; BIO_clear_retry_flags(b); ret = (outl >= 0 && (size_t)outl > bm->length) ? (int)bm->length : outl; if ((out != NULL) && (ret > 0)) { memcpy(out, bm->data, ret); bm->length -= ret; + bm->max -= ret; bm->data += ret; } else if (bm->length == 0) { ret = b->num; @@ -238,29 +251,34 @@ static long mem_ctrl(BIO *b, int cmd, long num, void *ptr) BIO_BUF_MEM *bbm = (BIO_BUF_MEM *)b->ptr; BUF_MEM *bm; + if (b->flags & BIO_FLAGS_MEM_RDONLY) + bm = bbm->buf; + else + bm = bbm->readp; + switch (cmd) { case BIO_CTRL_RESET: bm = bbm->buf; if (bm->data != NULL) { - /* For read only case reset to the start again */ - if ((b->flags & BIO_FLAGS_MEM_RDONLY) || (b->flags & BIO_FLAGS_NONCLEAR_RST)) { - bm->length = bm->max; + if (!(b->flags & BIO_FLAGS_MEM_RDONLY)) { + if (!(b->flags & BIO_FLAGS_NONCLEAR_RST)) { + memset(bm->data, 0, bm->max); + bm->length = 0; + } + *bbm->readp = *bbm->buf; } else { - memset(bm->data, 0, bm->max); - bm->length = 0; + /* For read only case just reset to the start again */ + *bbm->buf = *bbm->readp; } - *bbm->readp = *bbm->buf; } break; case BIO_CTRL_EOF: - bm = bbm->readp; ret = (long)(bm->length == 0); break; case BIO_C_SET_BUF_MEM_EOF_RETURN: b->num = (int)num; break; case BIO_CTRL_INFO: - bm = bbm->readp; ret = (long)bm->length; if (ptr != NULL) { pptr = (char **)ptr; @@ -268,16 +286,16 @@ static long mem_ctrl(BIO *b, int cmd, long num, void *ptr) } break; case BIO_C_SET_BUF_MEM: - mem_buf_free(b, 0); + mem_buf_free(b); b->shutdown = (int)num; bbm->buf = ptr; *bbm->readp = *bbm->buf; - b->ptr = bbm; break; case BIO_C_GET_BUF_MEM_PTR: if (ptr != NULL) { - mem_buf_sync(b); - bm = bbm->readp; + if (!(b->flags & BIO_FLAGS_MEM_RDONLY)) + mem_buf_sync(b); + bm = bbm->buf; pptr = (char **)ptr; *pptr = (char *)bm; } @@ -292,7 +310,6 @@ static long mem_ctrl(BIO *b, int cmd, long num, void *ptr) ret = 0L; break; case BIO_CTRL_PENDING: - bm = bbm->readp; ret = (long)bm->length; break; case BIO_CTRL_DUP: @@ -316,6 +333,8 @@ static int mem_gets(BIO *bp, char *buf, int size) BIO_BUF_MEM *bbm = (BIO_BUF_MEM *)bp->ptr; BUF_MEM *bm = bbm->readp; + if (bp->flags & BIO_FLAGS_MEM_RDONLY) + bm = bbm->buf; BIO_clear_retry_flags(bp); j = bm->length; if ((size - 1) < j) |