upadte memory bio read and setting bios in ssl struct

This commit is contained in:
Jacob Barthelmeh
2017-04-20 21:29:16 -06:00
parent d0d762c1a2
commit fcb1a10a3c
7 changed files with 174 additions and 32 deletions

View File

@@ -295,7 +295,6 @@ static int wolfSSL_BIO_MEMORY_write(WOLFSSL_BIO* bio, const void* data,
{
/* internal function where arguments have already been sanity checked */
int sz;
int ret;
const unsigned char* buf;
WOLFSSL_ENTER("wolfSSL_BIO_MEMORY_write");
@@ -307,8 +306,7 @@ static int wolfSSL_BIO_MEMORY_write(WOLFSSL_BIO* bio, const void* data,
}
if (bio->mem == NULL) {
bio->mem = (byte*)XMALLOC(len, bio->heap,
DYNAMIC_TYPE_OPENSSL);
bio->mem = (byte*)XMALLOC(len, bio->heap, DYNAMIC_TYPE_OPENSSL);
if (bio->mem == NULL) {
WOLFSSL_MSG("Error on malloc");
return SSL_FAILURE;
@@ -321,22 +319,20 @@ static int wolfSSL_BIO_MEMORY_write(WOLFSSL_BIO* bio, const void* data,
}
/* check if will fit in current buffer size */
if ((ret = wolfSSL_BIO_get_mem_data(bio, (void*)&buf)) < sz + len) {
if (ret <= 0) {
return WOLFSSL_BIO_ERROR;
if (wolfSSL_BIO_get_mem_data(bio, (void*)&buf) < 0) {
return WOLFSSL_BIO_ERROR;
}
if (bio->memLen < sz + len) {
bio->mem = (byte*)XREALLOC(bio->mem, sz + len, bio->heap,
DYNAMIC_TYPE_OPENSSL);
if (bio->mem == NULL) {
WOLFSSL_MSG("Error on realloc");
return SSL_FAILURE;
}
else {
bio->mem = (byte*)XREALLOC(bio->mem, sz + len, bio->heap,
DYNAMIC_TYPE_OPENSSL);
if (bio->mem == NULL) {
WOLFSSL_MSG("Error on realloc");
return SSL_FAILURE;
}
bio->memLen = sz + len;
if (bio->mem_buf != NULL) {
bio->mem_buf->data = (char*)bio->mem;
bio->mem_buf->length = bio->memLen;
}
bio->memLen = sz + len;
if (bio->mem_buf != NULL) {
bio->mem_buf->data = (char*)bio->mem;
bio->mem_buf->length = bio->memLen;
}
}
@@ -966,6 +962,19 @@ int wolfSSL_BIO_reset(WOLFSSL_BIO *bio)
bio->wrIdx = 0;
return 0;
case WOLFSSL_BIO_MEMORY:
bio->rdIdx = 0;
bio->wrIdx = 0;
bio->wrSz = 0;
XFREE(bio->mem, bio->heap, DYNAMIC_TYPE_BIO);
bio->mem = NULL;
bio->memLen = 0;
if (bio->mem_buf != NULL) {
bio->mem_buf->data = (char*)bio->mem;
bio->mem_buf->length = bio->memLen;
}
return 0;
default:
WOLFSSL_MSG("Unknown BIO type needs added to reset function");
}

View File

@@ -1503,6 +1503,11 @@ void SSL_CtxResourceFree(WOLFSSL_CTX* ctx)
FreeDer(&ctx->certChain);
wolfSSL_CertManagerFree(ctx->cm);
#ifdef OPENSSL_EXTRA
/* ctx->cm was free'd so cm of x509 store should now be NULL */
if (ctx->x509_store_pt != NULL) {
ctx->x509_store_pt->cm = NULL;
}
wolfSSL_X509_STORE_free(ctx->x509_store_pt);
while (ctx->ca_names != NULL) {
WOLFSSL_STACK *next = ctx->ca_names->next;
wolfSSL_X509_NAME_free(ctx->ca_names->data.name);
@@ -4070,6 +4075,8 @@ int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup)
#endif
#endif
ssl->CBIORecv = ctx->CBIORecv;
ssl->CBIOSend = ctx->CBIOSend;
#ifdef OPENSSL_EXTRA
ssl->readAhead = ctx->readAhead;
#endif
@@ -6118,13 +6125,13 @@ static int wolfSSLReceive(WOLFSSL* ssl, byte* buf, word32 sz)
{
int recvd;
if (ssl->ctx->CBIORecv == NULL) {
if (ssl->CBIORecv == NULL) {
WOLFSSL_MSG("Your IO Recv callback is null, please set");
return -1;
}
retry:
recvd = ssl->ctx->CBIORecv(ssl, (char *)buf, (int)sz, ssl->IOCB_ReadCtx);
recvd = ssl->CBIORecv(ssl, (char *)buf, (int)sz, ssl->IOCB_ReadCtx);
if (recvd < 0)
switch (recvd) {
case WOLFSSL_CBIO_ERR_GENERAL: /* general/unknown error */
@@ -6224,7 +6231,7 @@ void ShrinkInputBuffer(WOLFSSL* ssl, int forcedFree)
int SendBuffered(WOLFSSL* ssl)
{
if (ssl->ctx->CBIOSend == NULL) {
if (ssl->CBIOSend == NULL) {
WOLFSSL_MSG("Your IO Send callback is null, please set");
return SOCKET_ERROR_E;
}
@@ -6238,7 +6245,7 @@ int SendBuffered(WOLFSSL* ssl)
#endif
while (ssl->buffers.outputBuffer.length > 0) {
int sent = ssl->ctx->CBIOSend(ssl,
int sent = ssl->CBIOSend(ssl,
(char*)ssl->buffers.outputBuffer.buffer +
ssl->buffers.outputBuffer.idx,
(int)ssl->buffers.outputBuffer.length,

View File

@@ -11392,9 +11392,20 @@ int wolfSSL_set_compression(WOLFSSL* ssl)
#ifdef OPENSSL_EXTRA
void wolfSSL_set_bio(WOLFSSL* ssl, WOLFSSL_BIO* rd, WOLFSSL_BIO* wr)
{
WOLFSSL_ENTER("SSL_set_bio");
wolfSSL_set_rfd(ssl, rd->fd);
wolfSSL_set_wfd(ssl, wr->fd);
WOLFSSL_ENTER("wolfSSL_set_bio");
if (ssl == NULL) {
WOLFSSL_MSG("Bad argument, ssl was NULL");
return;
}
/* if WOLFSSL_BIO is socket type then set WOLFSSL socket to use */
if (rd != NULL && rd->type == WOLFSSL_BIO_SOCKET) {
wolfSSL_set_rfd(ssl, rd->fd);
}
if (wr != NULL && wr->type == WOLFSSL_BIO_SOCKET) {
wolfSSL_set_wfd(ssl, wr->fd);
}
/* free any existing WOLFSSL_BIOs in use */
if (ssl->biord != NULL) {
@@ -11411,6 +11422,14 @@ int wolfSSL_set_compression(WOLFSSL* ssl)
ssl->biord = rd;
ssl->biowr = wr;
/* set SSL to use BIO callbacks instead */
if (rd->type != WOLFSSL_BIO_SOCKET) {
ssl->CBIORecv = BioReceive;
}
if (wr->type != WOLFSSL_BIO_SOCKET) {
ssl->CBIOSend = BioSend;
}
}
#endif
@@ -11904,6 +11923,8 @@ int wolfSSL_set_compression(WOLFSSL* ssl)
}
ctx->cm = str->cm;
ctx->x509_store.cache = str->cache;
ctx->x509_store_pt = str; /* take ownership of store and free it
with CTX free */
}
@@ -12283,8 +12304,7 @@ int wolfSSL_set_compression(WOLFSSL* ssl)
wc_RemoveErrorNode(-1);
return ret;
}
#elif defined(DEBUG_WOLFSSL) && \
(defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE))
#elif (defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE))
return wc_PullErrorNode(NULL, NULL, NULL);
#else
return (unsigned long)(0 - NOT_COMPILED_IN);
@@ -28253,7 +28273,7 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl)
#if defined(HAVE_LIGHTY) || defined(WOLFSSL_MYSQL_COMPATIBLE) || \
defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || defined(HAVE_POCO_LIB) \
|| defined(WOLFSSL_HAPROXY)
|| defined(WOLFSSL_HAPROXY) || defined(OPENSSL_EXTRA)
#ifndef NO_WOLFSSL_STUB
unsigned char *wolfSSL_SHA1(const unsigned char *d, size_t n, unsigned char *md)
@@ -29406,6 +29426,7 @@ int wolfSSL_CIPHER_get_bits(const WOLFSSL_CIPHER *c, int *alg_bits)
}
return ret;
}
#endif /* #if defined(OPENSSL_EXTRA) && (defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX)) */
int wolfSSL_sk_X509_NAME_num(const WOLF_STACK_OF(WOLFSSL_X509_NAME) *s)
@@ -29427,6 +29448,9 @@ int wolfSSL_sk_X509_num(const WOLF_STACK_OF(WOLFSSL_X509) *s)
return (int)s->num;
}
/* stunnel compatibility functions*/
#if defined(OPENSSL_EXTRA) && (defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX))
int wolfSSL_X509_NAME_print_ex(WOLFSSL_BIO* bio, WOLFSSL_X509_NAME* name,
int indent, unsigned long flags)
{

View File

@@ -102,6 +102,95 @@ static INLINE int wolfSSL_LastError(void)
#endif /* USE_WOLFSSL_IO || HAVE_HTTP_CLIENT */
/* Use the WOLFSSL read BIO for receiving data. This is set by the fucntion wolfSSL_set_bio and can also be set by wolfSSL_SetIORecv.
*
* ssl WOLFSSL struct passed in that has this function set as the receive callback.
* buf buffer to fill with data read
* sz size of buf buffer
* ctx a user set context
*
* returns the amount of data read or want read. See WOLFSSL_CBIO_ERR_* values.
*/
int BioReceive(WOLFSSL* ssl, char* buf, int sz, void* ctx)
{
int recvd = WOLFSSL_CBIO_ERR_GENERAL;
WOLFSSL_ENTER("BioReceive");
#ifdef OPENSSL_EXTRA
if (ssl->biord == NULL) {
WOLFSSL_MSG("WOLFSSL biord not set");
return WOLFSSL_CBIO_ERR_GENERAL;
}
switch (ssl->biord->type) {
case WOLFSSL_BIO_MEMORY:
if (wolfSSL_BIO_ctrl_pending(ssl->biord) == 0) {
return WOLFSSL_CBIO_ERR_WANT_READ;
}
recvd = wolfSSL_BIO_read(ssl->biord, buf, sz);
if (recvd <= 0) {
return WOLFSSL_CBIO_ERR_GENERAL;
}
break;
default:
WOLFSSL_MSG("This BIO type is unknown / unsupported");
return WOLFSSL_CBIO_ERR_GENERAL;
}
#else
(void)ssl;
(void)buf;
(void)sz;
WOLFSSL_MSG("OPENSSL_EXTRA not compiled in");
#endif
(void)ctx;
return recvd;
}
/* Use the WOLFSSL write BIO for sending data. This is set by the fucntion wolfSSL_set_bio and can also be set by wolfSSL_SetIOSend.
*
* ssl WOLFSSL struct passed in that has this function set as the send callback.
* buf buffer with data to write out
* sz size of buf buffer
* ctx a user set context
*
* returns the amount of data sent or want send. See WOLFSSL_CBIO_ERR_* values.
*/
int BioSend(WOLFSSL* ssl, char *buf, int sz, void *ctx)
{
int sent = WOLFSSL_CBIO_ERR_GENERAL;
#ifdef OPENSSL_EXTRA
if (ssl->biowr == NULL) {
WOLFSSL_MSG("WOLFSSL biowr not set\n");
return WOLFSSL_CBIO_ERR_GENERAL;
}
switch (ssl->biowr->type) {
case WOLFSSL_BIO_MEMORY:
sent = wolfSSL_BIO_write(ssl->biowr, buf, sz);
if (sent < 0) {
return WOLFSSL_CBIO_ERR_GENERAL;
}
break;
default:
WOLFSSL_MSG("This BIO type is unknown / unsupported");
return WOLFSSL_CBIO_ERR_GENERAL;
}
#else
(void)ssl;
(void)buf;
(void)sz;
WOLFSSL_MSG("OPENSSL_EXTRA not compiled in");
#endif
(void)ctx;
return sent;
}
#ifdef USE_WOLFSSL_IO
/* The receive embedded callback

View File

@@ -30,7 +30,10 @@
#include <wolfssl/wolfcrypt/logging.h>
#include <wolfssl/wolfcrypt/error-crypt.h>
#if defined(OPENSSL_EXTRA) && !defined(WOLFCRYPT_ONLY)
/* avoid adding WANT_READ and WANT_WRITE to error queue */
#include <wolfssl/error-ssl.h>
#endif
#if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE)
static wolfSSL_Mutex debug_mutex; /* mutex for access to debug structure */
@@ -247,6 +250,11 @@ void WOLFSSL_ERROR(int error)
"wolfSSL error occurred, error = %d", error);
}
else {
#if defined(OPENSSL_EXTRA) && !defined(WOLFCRYPT_ONLY)
/* If running in compatibility mode do not add want read and
want right to error queue */
if (error != WANT_READ && error != WANT_WRITE) {
#endif
if (error < 0)
error = error - (2 * error); /* get absolute value */
XSNPRINTF(buffer, sizeof(buffer),
@@ -257,6 +265,9 @@ void WOLFSSL_ERROR(int error)
/* with void function there is no return here, continue on
* to unlock mutex and log what buffer was created. */
}
#if defined(OPENSSL_EXTRA) && !defined(WOLFCRYPT_ONLY)
}
#endif
wc_UnLockMutex(&debug_mutex);
}
@@ -315,8 +326,6 @@ int wc_LoggingCleanup(void)
}
#if defined(DEBUG_WOLFSSL) || defined(WOLFSSL_NGINX) || \
defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_MYSQL_COMPATIBLE)
/* peek at an error node
*
* idx : if -1 then the most recent node is looked at, otherwise search
@@ -530,7 +539,6 @@ void wc_RemoveErrorNode(int idx)
wc_UnLockMutex(&debug_mutex);
}
#endif /* DEBUG_WOLFSSL || WOLFSSL_NGINX */
/* Clears out the list of error nodes.
*/

View File

@@ -2349,6 +2349,7 @@ struct WOLFSSL_CTX {
pem_password_cb* passwd_cb;
void* userdata;
WOLFSSL_X509_STORE x509_store; /* points to ctx->cm */
WOLFSSL_X509_STORE* x509_store_pt; /* take ownership of external store */
byte readAhead;
void* userPRFArg; /* passed to prf callback */
#endif
@@ -3283,6 +3284,8 @@ struct WOLFSSL {
/* side that decrements dupCount to zero frees overall structure */
byte dupSide; /* write side or read side */
#endif
CallbackIORecv CBIORecv;
CallbackIOSend CBIOSend;
#ifdef WOLFSSL_STATIC_MEMORY
WOLFSSL_HEAP_HINT heap_hint;
#endif

View File

@@ -292,6 +292,8 @@ WOLFSSL_API int wolfIO_Recv(SOCKET_T sd, char *buf, int sz, int rdFlags);
#endif /* USE_WOLFSSL_IO || HAVE_HTTP_CLIENT */
WOLFSSL_API int BioSend(WOLFSSL* ssl, char *buf, int sz, void *ctx);
WOLFSSL_API int BioReceive(WOLFSSL* ssl, char* buf, int sz, void* ctx);
#if defined(USE_WOLFSSL_IO)
/* default IO callbacks */
WOLFSSL_API int EmbedReceive(WOLFSSL* ssl, char* buf, int sz, void* ctx);