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 */ /* internal function where arguments have already been sanity checked */
int sz; int sz;
int ret;
const unsigned char* buf; const unsigned char* buf;
WOLFSSL_ENTER("wolfSSL_BIO_MEMORY_write"); 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) { if (bio->mem == NULL) {
bio->mem = (byte*)XMALLOC(len, bio->heap, bio->mem = (byte*)XMALLOC(len, bio->heap, DYNAMIC_TYPE_OPENSSL);
DYNAMIC_TYPE_OPENSSL);
if (bio->mem == NULL) { if (bio->mem == NULL) {
WOLFSSL_MSG("Error on malloc"); WOLFSSL_MSG("Error on malloc");
return SSL_FAILURE; 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 */ /* check if will fit in current buffer size */
if ((ret = wolfSSL_BIO_get_mem_data(bio, (void*)&buf)) < sz + len) { if (wolfSSL_BIO_get_mem_data(bio, (void*)&buf) < 0) {
if (ret <= 0) { return WOLFSSL_BIO_ERROR;
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->memLen = sz + len;
bio->mem = (byte*)XREALLOC(bio->mem, sz + len, bio->heap, if (bio->mem_buf != NULL) {
DYNAMIC_TYPE_OPENSSL); bio->mem_buf->data = (char*)bio->mem;
if (bio->mem == NULL) { bio->mem_buf->length = bio->memLen;
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;
}
} }
} }
@@ -966,6 +962,19 @@ int wolfSSL_BIO_reset(WOLFSSL_BIO *bio)
bio->wrIdx = 0; bio->wrIdx = 0;
return 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: default:
WOLFSSL_MSG("Unknown BIO type needs added to reset function"); 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); FreeDer(&ctx->certChain);
wolfSSL_CertManagerFree(ctx->cm); wolfSSL_CertManagerFree(ctx->cm);
#ifdef OPENSSL_EXTRA #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) { while (ctx->ca_names != NULL) {
WOLFSSL_STACK *next = ctx->ca_names->next; WOLFSSL_STACK *next = ctx->ca_names->next;
wolfSSL_X509_NAME_free(ctx->ca_names->data.name); 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
#endif #endif
ssl->CBIORecv = ctx->CBIORecv;
ssl->CBIOSend = ctx->CBIOSend;
#ifdef OPENSSL_EXTRA #ifdef OPENSSL_EXTRA
ssl->readAhead = ctx->readAhead; ssl->readAhead = ctx->readAhead;
#endif #endif
@@ -6118,13 +6125,13 @@ static int wolfSSLReceive(WOLFSSL* ssl, byte* buf, word32 sz)
{ {
int recvd; int recvd;
if (ssl->ctx->CBIORecv == NULL) { if (ssl->CBIORecv == NULL) {
WOLFSSL_MSG("Your IO Recv callback is null, please set"); WOLFSSL_MSG("Your IO Recv callback is null, please set");
return -1; return -1;
} }
retry: 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) if (recvd < 0)
switch (recvd) { switch (recvd) {
case WOLFSSL_CBIO_ERR_GENERAL: /* general/unknown error */ case WOLFSSL_CBIO_ERR_GENERAL: /* general/unknown error */
@@ -6224,7 +6231,7 @@ void ShrinkInputBuffer(WOLFSSL* ssl, int forcedFree)
int SendBuffered(WOLFSSL* ssl) int SendBuffered(WOLFSSL* ssl)
{ {
if (ssl->ctx->CBIOSend == NULL) { if (ssl->CBIOSend == NULL) {
WOLFSSL_MSG("Your IO Send callback is null, please set"); WOLFSSL_MSG("Your IO Send callback is null, please set");
return SOCKET_ERROR_E; return SOCKET_ERROR_E;
} }
@@ -6238,7 +6245,7 @@ int SendBuffered(WOLFSSL* ssl)
#endif #endif
while (ssl->buffers.outputBuffer.length > 0) { while (ssl->buffers.outputBuffer.length > 0) {
int sent = ssl->ctx->CBIOSend(ssl, int sent = ssl->CBIOSend(ssl,
(char*)ssl->buffers.outputBuffer.buffer + (char*)ssl->buffers.outputBuffer.buffer +
ssl->buffers.outputBuffer.idx, ssl->buffers.outputBuffer.idx,
(int)ssl->buffers.outputBuffer.length, (int)ssl->buffers.outputBuffer.length,

View File

@@ -11392,9 +11392,20 @@ int wolfSSL_set_compression(WOLFSSL* ssl)
#ifdef OPENSSL_EXTRA #ifdef OPENSSL_EXTRA
void wolfSSL_set_bio(WOLFSSL* ssl, WOLFSSL_BIO* rd, WOLFSSL_BIO* wr) void wolfSSL_set_bio(WOLFSSL* ssl, WOLFSSL_BIO* rd, WOLFSSL_BIO* wr)
{ {
WOLFSSL_ENTER("SSL_set_bio"); WOLFSSL_ENTER("wolfSSL_set_bio");
wolfSSL_set_rfd(ssl, rd->fd);
wolfSSL_set_wfd(ssl, wr->fd); 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 */ /* free any existing WOLFSSL_BIOs in use */
if (ssl->biord != NULL) { if (ssl->biord != NULL) {
@@ -11411,6 +11422,14 @@ int wolfSSL_set_compression(WOLFSSL* ssl)
ssl->biord = rd; ssl->biord = rd;
ssl->biowr = wr; 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 #endif
@@ -11904,6 +11923,8 @@ int wolfSSL_set_compression(WOLFSSL* ssl)
} }
ctx->cm = str->cm; ctx->cm = str->cm;
ctx->x509_store.cache = str->cache; 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); wc_RemoveErrorNode(-1);
return ret; return ret;
} }
#elif defined(DEBUG_WOLFSSL) && \ #elif (defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE))
(defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE))
return wc_PullErrorNode(NULL, NULL, NULL); return wc_PullErrorNode(NULL, NULL, NULL);
#else #else
return (unsigned long)(0 - NOT_COMPILED_IN); return (unsigned long)(0 - NOT_COMPILED_IN);
@@ -28253,7 +28273,7 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl)
#if defined(HAVE_LIGHTY) || defined(WOLFSSL_MYSQL_COMPATIBLE) || \ #if defined(HAVE_LIGHTY) || defined(WOLFSSL_MYSQL_COMPATIBLE) || \
defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || defined(HAVE_POCO_LIB) \ defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || defined(HAVE_POCO_LIB) \
|| defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_HAPROXY) || defined(OPENSSL_EXTRA)
#ifndef NO_WOLFSSL_STUB #ifndef NO_WOLFSSL_STUB
unsigned char *wolfSSL_SHA1(const unsigned char *d, size_t n, unsigned char *md) 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; 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) 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; 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 wolfSSL_X509_NAME_print_ex(WOLFSSL_BIO* bio, WOLFSSL_X509_NAME* name,
int indent, unsigned long flags) int indent, unsigned long flags)
{ {

View File

@@ -102,6 +102,95 @@ static INLINE int wolfSSL_LastError(void)
#endif /* USE_WOLFSSL_IO || HAVE_HTTP_CLIENT */ #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 #ifdef USE_WOLFSSL_IO
/* The receive embedded callback /* The receive embedded callback

View File

@@ -30,7 +30,10 @@
#include <wolfssl/wolfcrypt/logging.h> #include <wolfssl/wolfcrypt/logging.h>
#include <wolfssl/wolfcrypt/error-crypt.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) #if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE)
static wolfSSL_Mutex debug_mutex; /* mutex for access to debug structure */ 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); "wolfSSL error occurred, error = %d", error);
} }
else { 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) if (error < 0)
error = error - (2 * error); /* get absolute value */ error = error - (2 * error); /* get absolute value */
XSNPRINTF(buffer, sizeof(buffer), XSNPRINTF(buffer, sizeof(buffer),
@@ -257,6 +265,9 @@ void WOLFSSL_ERROR(int error)
/* with void function there is no return here, continue on /* with void function there is no return here, continue on
* to unlock mutex and log what buffer was created. */ * to unlock mutex and log what buffer was created. */
} }
#if defined(OPENSSL_EXTRA) && !defined(WOLFCRYPT_ONLY)
}
#endif
wc_UnLockMutex(&debug_mutex); 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 /* peek at an error node
* *
* idx : if -1 then the most recent node is looked at, otherwise search * 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); wc_UnLockMutex(&debug_mutex);
} }
#endif /* DEBUG_WOLFSSL || WOLFSSL_NGINX */
/* Clears out the list of error nodes. /* Clears out the list of error nodes.
*/ */

View File

@@ -2349,6 +2349,7 @@ struct WOLFSSL_CTX {
pem_password_cb* passwd_cb; pem_password_cb* passwd_cb;
void* userdata; void* userdata;
WOLFSSL_X509_STORE x509_store; /* points to ctx->cm */ WOLFSSL_X509_STORE x509_store; /* points to ctx->cm */
WOLFSSL_X509_STORE* x509_store_pt; /* take ownership of external store */
byte readAhead; byte readAhead;
void* userPRFArg; /* passed to prf callback */ void* userPRFArg; /* passed to prf callback */
#endif #endif
@@ -3283,6 +3284,8 @@ struct WOLFSSL {
/* side that decrements dupCount to zero frees overall structure */ /* side that decrements dupCount to zero frees overall structure */
byte dupSide; /* write side or read side */ byte dupSide; /* write side or read side */
#endif #endif
CallbackIORecv CBIORecv;
CallbackIOSend CBIOSend;
#ifdef WOLFSSL_STATIC_MEMORY #ifdef WOLFSSL_STATIC_MEMORY
WOLFSSL_HEAP_HINT heap_hint; WOLFSSL_HEAP_HINT heap_hint;
#endif #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 */ #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) #if defined(USE_WOLFSSL_IO)
/* default IO callbacks */ /* default IO callbacks */
WOLFSSL_API int EmbedReceive(WOLFSSL* ssl, char* buf, int sz, void* ctx); WOLFSSL_API int EmbedReceive(WOLFSSL* ssl, char* buf, int sz, void* ctx);