diff --git a/src/bio.c b/src/bio.c index 340cbfdac..318fca66c 100644 --- a/src/bio.c +++ b/src/bio.c @@ -145,6 +145,7 @@ static int wolfSSL_BIO_MEMORY_read(WOLFSSL_BIO* bio, void* buf, int len) XMEMCPY(buf, bio->mem_buf->data + bio->rdIdx, sz); bio->rdIdx += sz; + bio->bytes_read += (word32)sz; if (bio->rdIdx >= bio->wrSz) { if (bio->flags & BIO_FLAGS_MEM_RDONLY) { @@ -580,6 +581,7 @@ static int wolfSSL_BIO_MEMORY_write(WOLFSSL_BIO* bio, const void* data, bio->num = (int)bio->mem_buf->max; bio->wrSz += len; bio->wrIdx += len; + bio->bytes_written += (word32)len; return len; } @@ -1387,6 +1389,7 @@ int wolfSSL_BIO_nread(WOLFSSL_BIO *bio, char **buf, int num) sz = num; } bio->pair->rdIdx += sz; + bio->pair->bytes_read += (word32)sz; /* check if have read to the end of the buffer and need to reset */ if (bio->pair->rdIdx == bio->pair->wrSz) { @@ -1465,6 +1468,7 @@ int wolfSSL_BIO_nwrite(WOLFSSL_BIO *bio, char **buf, int num) } *buf = (char*)bio->ptr + bio->wrIdx; bio->wrIdx += sz; + bio->bytes_written += (word32)sz; /* if at the end of the buffer and space for wrap around then set * write index back to 0 */ @@ -1476,6 +1480,33 @@ int wolfSSL_BIO_nwrite(WOLFSSL_BIO *bio, char **buf, int num) return sz; } +#ifdef WORD64_AVAILABLE +word64 +#else +word32 +#endif +wolfSSL_BIO_number_read(WOLFSSL_BIO *bio) +{ + if (bio == NULL) { + WOLFSSL_MSG("NULL argument passed in"); + return 0; + } + return bio->bytes_read; +} + +#ifdef WORD64_AVAILABLE +word64 +#else +word32 +#endif +wolfSSL_BIO_number_written(WOLFSSL_BIO *bio) +{ + if (bio == NULL) { + WOLFSSL_MSG("NULL argument passed in"); + return 0; + } + return bio->bytes_written; +} /* Reset BIO to initial state */ int wolfSSL_BIO_reset(WOLFSSL_BIO *bio) diff --git a/src/ssl.c b/src/ssl.c index 36142b014..35dbdd86a 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -10950,6 +10950,83 @@ int wolfSSL_set_compression(WOLFSSL* ssl) #ifdef OPENSSL_EXTRA #ifndef NO_BIO + static void wolfSSL_set_bio_1(WOLFSSL* ssl, WOLFSSL_BIO* rd, WOLFSSL_BIO* wr, int flags) + { + WOLFSSL_ENTER("wolfSSL_set_bio"); + + if (ssl == NULL) { + WOLFSSL_MSG("Bad argument, ssl was NULL"); + return; + } + + /* free any existing WOLFSSL_BIOs in use but don't free those in + * a chain */ + if ((flags & WOLFSSL_BIO_FLAG_READ) && (ssl->biord != NULL)) { + if ((flags & WOLFSSL_BIO_FLAG_WRITE) && (ssl->biord != ssl->biowr)) { + if (ssl->biowr != NULL && ssl->biowr->prev != NULL) + wolfSSL_BIO_free(ssl->biowr); + ssl->biowr = NULL; + } + if (ssl->biord->prev != NULL) + wolfSSL_BIO_free(ssl->biord); + ssl->biord = NULL; + } + else if ((flags & WOLFSSL_BIO_FLAG_WRITE) && (ssl->biowr != NULL)) { + if (ssl->biowr->prev != NULL) + wolfSSL_BIO_free(ssl->biowr); + ssl->biowr = NULL; + } + + /* set flag obviously */ + if (rd && !(rd->flags & WOLFSSL_BIO_FLAG_READ)) + rd->flags |= WOLFSSL_BIO_FLAG_READ; + if (wr && !(wr->flags & WOLFSSL_BIO_FLAG_WRITE)) + wr->flags |= WOLFSSL_BIO_FLAG_WRITE; + + if (flags & WOLFSSL_BIO_FLAG_READ) + ssl->biord = rd; + if (flags & WOLFSSL_BIO_FLAG_WRITE) + ssl->biowr = wr; + + /* set SSL to use BIO callbacks instead */ + if ((flags & WOLFSSL_BIO_FLAG_READ) && + (((ssl->cbioFlag & WOLFSSL_CBIO_RECV) == 0))) + { + ssl->CBIORecv = BioReceive; + } + if ((flags & WOLFSSL_BIO_FLAG_WRITE) && + (((ssl->cbioFlag & WOLFSSL_CBIO_SEND) == 0))) + { + ssl->CBIOSend = BioSend; + } + + /* User programs should always retry reading from these BIOs */ + if (rd) { + /* User writes to rd */ + BIO_set_retry_write(rd); + } + if (wr) { + /* User reads from wr */ + BIO_set_retry_read(wr); + } + } + + void wolfSSL_set_bio(WOLFSSL* ssl, WOLFSSL_BIO* rd, WOLFSSL_BIO* wr) + { + wolfSSL_set_bio_1(ssl, rd, wr, WOLFSSL_BIO_FLAG_READ | WOLFSSL_BIO_FLAG_WRITE); + } + + void wolfSSL_set_rbio(WOLFSSL* ssl, WOLFSSL_BIO* rd) + { + wolfSSL_set_bio_1(ssl, rd, NULL, WOLFSSL_BIO_FLAG_READ); + } + + void wolfSSL_set_wbio(WOLFSSL* ssl, WOLFSSL_BIO* wr) + { + wolfSSL_set_bio_1(ssl, NULL, wr, WOLFSSL_BIO_FLAG_WRITE); + } + +#if 0 void wolfSSL_set_bio(WOLFSSL* ssl, WOLFSSL_BIO* rd, WOLFSSL_BIO* wr) { WOLFSSL_ENTER("wolfSSL_set_bio"); @@ -10971,6 +11048,12 @@ int wolfSSL_set_compression(WOLFSSL* ssl) wolfSSL_BIO_free(ssl->biord); ssl->biord = NULL; } + else if (ssl->biowr != NULL) { + if (ssl->biowr->prev != NULL) + wolfSSL_BIO_free(ssl->biowr); + ssl->biowr = NULL; + } + /* set flag obviously */ if (rd && !(rd->flags & WOLFSSL_BIO_FLAG_READ)) rd->flags |= WOLFSSL_BIO_FLAG_READ; @@ -10998,6 +11081,8 @@ int wolfSSL_set_compression(WOLFSSL* ssl) BIO_set_retry_read(wr); } } +#endif /* 0 */ + #endif /* !NO_BIO */ #endif /* OPENSSL_EXTRA */ diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index 7303bd5c8..8d92ae1ee 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -784,7 +784,9 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_ #define BIO_pop wolfSSL_BIO_pop #define BIO_flush wolfSSL_BIO_flush #define BIO_pending wolfSSL_BIO_pending - +#define BIO_number_read wolfSSL_BIO_number_read +#define BIO_number_written wolfSSL_BIO_number_written +#define BIO_reset wolfSSL_BIO_reset #define BIO_get_mem_data wolfSSL_BIO_get_mem_data #define BIO_new_mem_buf wolfSSL_BIO_new_mem_buf @@ -800,6 +802,8 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_ #define BIO_do_handshake wolfSSL_BIO_do_handshake #define BIO_ssl_shutdown wolfSSL_BIO_ssl_shutdown #define SSL_set_bio wolfSSL_set_bio +#define SSL_set0_rbio wolfSSL_set_rbio +#define SSL_set0_wbio wolfSSL_set_wbio #define BIO_method_type wolfSSL_BIO_method_type #define BIO_set_ssl wolfSSL_BIO_set_ssl #define BIO_get_ssl wolfSSL_BIO_get_ssl diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 809eb0879..4499caf0d 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -561,6 +561,15 @@ struct WOLFSSL_BIO { byte type; /* method type */ byte init:1; /* bio has been initialized */ byte shutdown:1; /* close flag */ + +#ifdef WORD64_AVAILABLE + word64 bytes_read; + word64 bytes_written; +#else + word32 bytes_read; + word32 bytes_written; +#endif + #ifdef HAVE_EX_DATA WOLFSSL_CRYPTO_EX_DATA ex_data; #endif @@ -1812,6 +1821,8 @@ WOLFSSL_API long wolfSSL_BIO_set_fd(WOLFSSL_BIO* b, int fd, int flag); #endif WOLFSSL_API int wolfSSL_BIO_set_close(WOLFSSL_BIO *b, long flag); WOLFSSL_API void wolfSSL_set_bio(WOLFSSL* ssl, WOLFSSL_BIO* rd, WOLFSSL_BIO* wr); +WOLFSSL_API void wolfSSL_set_rbio(WOLFSSL* ssl, WOLFSSL_BIO* rd); +WOLFSSL_API void wolfSSL_set_wbio(WOLFSSL* ssl, WOLFSSL_BIO* wr); WOLFSSL_API int wolfSSL_BIO_method_type(const WOLFSSL_BIO *b); #ifndef NO_FILESYSTEM @@ -1844,6 +1855,13 @@ WOLFSSL_API int wolfSSL_BIO_ctrl_reset_read_request(WOLFSSL_BIO *b); WOLFSSL_API int wolfSSL_BIO_nread0(WOLFSSL_BIO *bio, char **buf); WOLFSSL_API int wolfSSL_BIO_nread(WOLFSSL_BIO *bio, char **buf, int num); WOLFSSL_API int wolfSSL_BIO_nwrite(WOLFSSL_BIO *bio, char **buf, int num); +#ifdef WORD64_AVAILABLE +WOLFSSL_API word64 wolfSSL_BIO_number_read(WOLFSSL_BIO *bio); +WOLFSSL_API word64 wolfSSL_BIO_number_written(WOLFSSL_BIO *bio); +#else +WOLFSSL_API word32 wolfSSL_BIO_number_read(WOLFSSL_BIO *bio); +WOLFSSL_API word32 wolfSSL_BIO_number_written(WOLFSSL_BIO *bio); +#endif WOLFSSL_API int wolfSSL_BIO_reset(WOLFSSL_BIO *bio); WOLFSSL_API int wolfSSL_BIO_seek(WOLFSSL_BIO *bio, int ofs);