diff --git a/src/bio.c b/src/bio.c index ff5b83619..cc171291c 100644 --- a/src/bio.c +++ b/src/bio.c @@ -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"); } diff --git a/src/internal.c b/src/internal.c index f6e7e4fec..db511a393 100644 --- a/src/internal.c +++ b/src/internal.c @@ -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, diff --git a/src/ssl.c b/src/ssl.c index 28e0ab241..8f5beeaf4 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -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) { diff --git a/src/wolfio.c b/src/wolfio.c index 52a9b0076..e057d02b7 100644 --- a/src/wolfio.c +++ b/src/wolfio.c @@ -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 diff --git a/wolfcrypt/src/logging.c b/wolfcrypt/src/logging.c index dcfb3cd7d..c2fcec7c4 100644 --- a/wolfcrypt/src/logging.c +++ b/wolfcrypt/src/logging.c @@ -30,7 +30,10 @@ #include #include - +#if defined(OPENSSL_EXTRA) && !defined(WOLFCRYPT_ONLY) +/* avoid adding WANT_READ and WANT_WRITE to error queue */ +#include +#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. */ diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 5fe9f2747..e6f21d454 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -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 diff --git a/wolfssl/wolfio.h b/wolfssl/wolfio.h index 59afd029b..b451f36d5 100644 --- a/wolfssl/wolfio.h +++ b/wolfssl/wolfio.h @@ -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);