Fix for BIO_reset() (#5887)

* Fix for BIO_reset
* Introduced BIO_FLAGS_MEM_RDONLY
pull/6089/head
tmael 2023-02-14 08:54:25 -08:00 committed by GitHub
parent 2fe34facba
commit c4fa013800
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 66 additions and 24 deletions

View File

@ -128,19 +128,24 @@ static int wolfSSL_BIO_MEMORY_read(WOLFSSL_BIO* bio, void* buf, int len)
bio->rdIdx += sz;
if (bio->rdIdx >= bio->wrSz) {
/* All data read resize down to WOLFSSL_BIO_RESIZE_THRESHOLD */
if (bio->mem_buf->max > WOLFSSL_BIO_RESIZE_THRESHOLD &&
wolfSSL_BUF_MEM_resize(bio->mem_buf,
WOLFSSL_BIO_RESIZE_THRESHOLD) == 0) {
WOLFSSL_MSG("wolfSSL_BUF_MEM_resize error");
return WOLFSSL_BIO_ERROR;
if (bio->flags & BIO_FLAGS_MEM_RDONLY) {
bio->wrSz = bio->wrSzReset;
}
else {
/* All data read resize down to WOLFSSL_BIO_RESIZE_THRESHOLD */
if (bio->mem_buf->max > WOLFSSL_BIO_RESIZE_THRESHOLD &&
wolfSSL_BUF_MEM_resize(bio->mem_buf, WOLFSSL_BIO_RESIZE_THRESHOLD) == 0) {
WOLFSSL_MSG("wolfSSL_BUF_MEM_resize error");
return WOLFSSL_BIO_ERROR;
}
bio->rdIdx = 0;
bio->wrSz = 0;
bio->mem_buf->length = 0;
}
bio->wrSz = 0;
bio->rdIdx = 0;
bio->mem_buf->length = 0;
bio->ptr = bio->mem_buf->data;
}
else if (bio->rdIdx >= WOLFSSL_BIO_RESIZE_THRESHOLD) {
else if (bio->rdIdx >= WOLFSSL_BIO_RESIZE_THRESHOLD &&
!(bio->flags & BIO_FLAGS_MEM_RDONLY)) {
/* Resize the memory so we are not taking up more than necessary.
* memmove reverts internally to memcpy if areas don't overlap */
XMEMMOVE(bio->mem_buf->data, bio->mem_buf->data + bio->rdIdx,
@ -516,6 +521,9 @@ static int wolfSSL_BIO_MEMORY_write(WOLFSSL_BIO* bio, const void* data,
WOLFSSL_MSG("one of input parameters is null");
return WOLFSSL_FAILURE;
}
if (bio->flags & BIO_FLAGS_MEM_RDONLY) {
return WOLFSSL_FAILURE;
}
if (len == 0)
return WOLFSSL_SUCCESS; /* Return early to make logic simpler */
@ -535,6 +543,7 @@ static int wolfSSL_BIO_MEMORY_write(WOLFSSL_BIO* bio, const void* data,
bio->ptr = bio->mem_buf->data;
bio->num = (int)bio->mem_buf->max;
bio->wrSz += len;
bio->wrIdx += len;
return len;
}
@ -1431,15 +1440,20 @@ int wolfSSL_BIO_reset(WOLFSSL_BIO *bio)
case WOLFSSL_BIO_MEMORY:
bio->rdIdx = 0;
bio->wrIdx = 0;
bio->wrSz = 0;
XFREE(bio->ptr, bio->heap, DYNAMIC_TYPE_OPENSSL);
bio->ptr = NULL;
bio->num = 0;
if (bio->mem_buf != NULL) {
bio->mem_buf->data = NULL;
bio->mem_buf->length = 0;
bio->mem_buf->max = 0;
if (bio->flags & BIO_FLAGS_MEM_RDONLY) {
bio->wrIdx = bio->wrSzReset;
bio->wrSz = bio->wrSzReset;
}
else {
bio->wrSz = 0;
XFREE(bio->ptr, bio->heap, DYNAMIC_TYPE_OPENSSL);
bio->ptr = NULL;
bio->num = 0;
if (bio->mem_buf != NULL) {
bio->mem_buf->data = NULL;
bio->mem_buf->length = 0;
bio->mem_buf->max = 0;
}
}
return 0;
@ -2542,6 +2556,8 @@ int wolfSSL_BIO_flush(WOLFSSL_BIO* bio)
bio->ptr = bio->mem_buf->data;
if (len > 0 && bio->ptr != NULL) {
XMEMCPY(bio->ptr, buf, len);
bio->flags |= BIO_FLAGS_MEM_RDONLY;
bio->wrSzReset = bio->wrSz;
}
return bio;

View File

@ -9319,13 +9319,9 @@ static int test_wolfSSL_PKCS12(void)
goodPswLen = (int)XSTRLEN(goodPsw);
badPswLen = (int)XSTRLEN(badPsw);
bio = BIO_new_mem_buf((void*)buf, bytes);
bio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem());
AssertNotNull(bio);
pkcs12 = d2i_PKCS12_bio(bio, NULL);
AssertNotNull(pkcs12);
PKCS12_free(pkcs12);
AssertIntEQ(BIO_write(bio, buf, bytes), bytes); /* d2i consumes BIO */
d2i_PKCS12_bio(bio, &pkcs12);
AssertNotNull(pkcs12);
@ -41239,7 +41235,32 @@ static int test_wolfSSL_BIO_up_ref(void)
#endif
return res;
}
static int test_wolfSSL_BIO_reset(void)
{
int res = TEST_SKIPPED;
#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)
BIO* bio;
byte buf[16];
AssertNotNull(bio = BIO_new_mem_buf("secure your data",
(word32)XSTRLEN("secure your data")));
AssertIntEQ(BIO_read(bio, buf, 6), 6);
AssertIntEQ(XMEMCMP(buf, "secure", 6), 0);
XMEMSET(buf, 0, 16);
AssertIntEQ(BIO_read(bio, buf, 16), 10);
AssertIntEQ(XMEMCMP(buf, " your data", 10), 0);
/* You cannot write to MEM BIO with read-only mode. */
AssertIntEQ(BIO_write(bio, "WriteToReadonly", 15), 0);
AssertIntEQ(BIO_read(bio, buf, 16), -1);
XMEMSET(buf, 0, 16);
AssertIntEQ(BIO_reset(bio), 0);
AssertIntEQ(BIO_read(bio, buf, 16), 16);
AssertIntEQ(XMEMCMP(buf, "secure your data", 16), 0);
BIO_free(bio);
res = TEST_RES_CHECK(1);
#endif
return res;
}
#endif /* !NO_BIO */
#if defined(OPENSSL_EXTRA) && defined(HAVE_IO_TESTS_DEPENDENCIES)
@ -61697,6 +61718,7 @@ TEST_CASE testCases[] = {
TEST_DECL(test_wolfSSL_BIO_f_md),
TEST_DECL(test_wolfSSL_BIO_up_ref),
TEST_DECL(test_wolfSSL_BIO_tls),
TEST_DECL(test_wolfSSL_BIO_reset),
#endif
TEST_DECL(test_wolfSSL_cert_cb),
TEST_DECL(test_wolfSSL_SESSION),

View File

@ -170,6 +170,9 @@
#define BIO_FP_WRITE 0x04
/* You shouldn't free up or change the data if BIO_FLAGS_MEM_RDONLY is set */
#define BIO_FLAGS_MEM_RDONLY 0x200
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */

View File

@ -544,6 +544,7 @@ struct WOLFSSL_BIO {
char* infoArg; /* BIO callback argument */
wolf_bio_info_cb infoCb; /* BIO callback */
int wrSz; /* write buffer size (mem) */
int wrSzReset; /* First buffer size (mem) - read ONLY data */
int wrIdx; /* current index for write buffer */
int rdIdx; /* current read index */
int readRq; /* read request */