Refactor BIO read/write to use switch.

This commit is contained in:
David Garske
2021-03-24 10:20:16 -07:00
parent 072e6e010c
commit 8984ce03e9
2 changed files with 139 additions and 144 deletions

View File

@ -1210,7 +1210,7 @@ int wc_PemCertToDer(const char* fileName, unsigned char* derBuf, int derSz);
and storing it as a pem file and storing it as a pem file
\return MEMORY_E Returned if there is an error allocating memory \return MEMORY_E Returned if there is an error allocating memory
with XMALLOC with XMALLOC
\return ASN_INPUT_E Returned in the case of a base 64 encoding error \return ASN_INPUT_E Returned in the case of a base64 encoding error
\return BUFFER_E May be returned if the output buffer is too small to \return BUFFER_E May be returned if the output buffer is too small to
store the pem formatted certificate store the pem formatted certificate
@ -1253,7 +1253,7 @@ WOLFSSL_API int wc_DerToPem(const byte* der, word32 derSz, byte* output,
and storing it as a pem file and storing it as a pem file
\return MEMORY_E Returned if there is an error allocating memory \return MEMORY_E Returned if there is an error allocating memory
with XMALLOC with XMALLOC
\return ASN_INPUT_E Returned in the case of a base 64 encoding error \return ASN_INPUT_E Returned in the case of a base64 encoding error
\return BUFFER_E May be returned if the output buffer is too small to \return BUFFER_E May be returned if the output buffer is too small to
store the pem formatted certificate store the pem formatted certificate

279
src/bio.c
View File

@ -40,7 +40,7 @@ static int wolfSSL_BIO_BASE64_read(WOLFSSL_BIO* bio, void* buf, int len)
if (Base64_Decode((const byte*)buf, (word32)len, (byte*)buf, &frmtSz) !=0) { if (Base64_Decode((const byte*)buf, (word32)len, (byte*)buf, &frmtSz) !=0) {
WOLFSSL_MSG("Err doing base64 decode"); WOLFSSL_MSG("Err doing base64 decode");
return SSL_FATAL_ERROR; return WOLFSSL_FATAL_ERROR;
} }
(void)bio; (void)bio;
@ -146,7 +146,7 @@ static int wolfSSL_BIO_SSL_read(WOLFSSL_BIO* bio, void* buf,
front->eof = 1; front->eof = 1;
else if (ret < 0) { else if (ret < 0) {
int err = wolfSSL_get_error((WOLFSSL*)bio->ptr, 0); int err = wolfSSL_get_error((WOLFSSL*)bio->ptr, 0);
if ( !(err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) ) { if ( !(err == WOLFSSL_ERROR_WANT_READ || err == WOLFSSL_ERROR_WANT_WRITE) ) {
front->eof = 1; front->eof = 1;
} }
else { else {
@ -187,9 +187,9 @@ static int wolfSSL_BIO_MD_read(WOLFSSL_BIO* bio, void* buf, int sz)
*/ */
int wolfSSL_BIO_read(WOLFSSL_BIO* bio, void* buf, int len) int wolfSSL_BIO_read(WOLFSSL_BIO* bio, void* buf, int len)
{ {
int ret = 0; int ret = 0;
WOLFSSL_BIO* front = bio; WOLFSSL_BIO* front = bio;
int sz = 0; int sz = 0;
WOLFSSL_ENTER("wolfSSL_BIO_read"); WOLFSSL_ENTER("wolfSSL_BIO_read");
@ -214,46 +214,44 @@ int wolfSSL_BIO_read(WOLFSSL_BIO* bio, void* buf, int len)
ret = bio->method->readCb(bio, (char*)buf, len); ret = bio->method->readCb(bio, (char*)buf, len);
} }
else { else {
/* formatting data */ switch (bio->type) {
if (bio->type == WOLFSSL_BIO_BASE64 && ret > 0 && sz > 0) { case WOLFSSL_BIO_BASE64: /* formatting data */
ret = wolfSSL_BIO_BASE64_read(bio, buf, sz); if (sz > 0)
} ret = wolfSSL_BIO_BASE64_read(bio, buf, sz);
break;
/* write BIOs */ case WOLFSSL_BIO_BIO: /* read BIOs */
if (bio && bio->type == WOLFSSL_BIO_BIO) {
ret = wolfSSL_BIO_BIO_read(bio, buf, len); ret = wolfSSL_BIO_BIO_read(bio, buf, len);
} break;
case WOLFSSL_BIO_MEMORY:
if (bio && bio->type == WOLFSSL_BIO_MEMORY) {
ret = wolfSSL_BIO_MEMORY_read(bio, buf, len); ret = wolfSSL_BIO_MEMORY_read(bio, buf, len);
} break;
case WOLFSSL_BIO_FILE:
#ifndef NO_FILESYSTEM #ifndef NO_FILESYSTEM
if (bio && bio->type == WOLFSSL_BIO_FILE) { if (bio->ptr) {
if (bio->ptr)
ret = (int)XFREAD(buf, 1, len, (XFILE)bio->ptr); ret = (int)XFREAD(buf, 1, len, (XFILE)bio->ptr);
#if !defined(USE_WINDOWS_API) && !defined(NO_WOLFSSL_DIR)\ }
&& !defined(WOLFSSL_NUCLEUS) && !defined(WOLFSSL_NUCLEUS_1_2) #if !defined(USE_WINDOWS_API) && !defined(NO_WOLFSSL_DIR) && \
else !defined(WOLFSSL_NUCLEUS) && !defined(WOLFSSL_NUCLEUS_1_2)
else {
ret = (int)XREAD(bio->num, buf, len); ret = (int)XREAD(bio->num, buf, len);
#endif }
} #endif
#endif #endif /* !NO_FILESYSTEM */
break;
#ifndef WOLFCRYPT_ONLY case WOLFSSL_BIO_SSL:
if (bio && bio->type == WOLFSSL_BIO_SSL) { #ifndef WOLFCRYPT_ONLY
ret = wolfSSL_BIO_SSL_read(bio, buf, len, front); ret = wolfSSL_BIO_SSL_read(bio, buf, len, front);
} #endif
break;
/* data passing through BIO MD wrapper */ case WOLFSSL_BIO_MD: /* data passing through BIO MD wrapper */
if (bio && bio->type == WOLFSSL_BIO_MD && ret > 0) { #ifndef WOLFCRYPT_ONLY
ret = wolfSSL_BIO_MD_read(bio, buf, ret); ret = wolfSSL_BIO_MD_read(bio, buf, ret);
} #endif
#endif break;
case WOLFSSL_BIO_SOCKET:
if (bio->type == WOLFSSL_BIO_SOCKET) {
ret = wolfIO_Recv(bio->num, (char*)buf, len, 0); ret = wolfIO_Recv(bio->num, (char*)buf, len, 0);
} break;
} /* switch */
} }
/* case where front of list is done */ /* case where front of list is done */
@ -280,6 +278,7 @@ int wolfSSL_BIO_read(WOLFSSL_BIO* bio, void* buf, int len)
} }
#ifdef WOLFSSL_BASE64_ENCODE
/* Converts data into base64 output /* Converts data into base64 output
* *
* returns the resulting buffer size on success. * returns the resulting buffer size on success.
@ -296,7 +295,6 @@ static int wolfSSL_BIO_BASE64_write(WOLFSSL_BIO* bio, const void* data,
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
} }
#if defined(WOLFSSL_BASE64_ENCODE)
tmp = (byte*)XMALLOC(*outLen, bio->heap, DYNAMIC_TYPE_TMP_BUFFER); tmp = (byte*)XMALLOC(*outLen, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
if (tmp == NULL) { if (tmp == NULL) {
return WOLFSSL_FATAL_ERROR; return WOLFSSL_FATAL_ERROR;
@ -322,18 +320,10 @@ static int wolfSSL_BIO_BASE64_write(WOLFSSL_BIO* bio, const void* data,
} }
XFREE(tmp, bio->heap, DYNAMIC_TYPE_TMP_BUFFER); XFREE(tmp, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
#else
(void)bio;
(void)data;
(void)inLen;
(void)out;
(void)outLen;
(void)tmp;
WOLFSSL_MSG("BASE64 encoding not compiled in");
#endif
return ret; return ret;
} }
#endif /* WOLFSSL_BASE64_ENCODE */
#ifndef WOLFCRYPT_ONLY #ifndef WOLFCRYPT_ONLY
/* Helper function for writing to a WOLFSSL_BIO_SSL type /* Helper function for writing to a WOLFSSL_BIO_SSL type
@ -357,7 +347,7 @@ static int wolfSSL_BIO_SSL_write(WOLFSSL_BIO* bio, const void* data,
front->eof = 1; front->eof = 1;
else if (ret < 0) { else if (ret < 0) {
int err = wolfSSL_get_error((WOLFSSL*)bio->ptr, 0); int err = wolfSSL_get_error((WOLFSSL*)bio->ptr, 0);
if ( !(err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) ) { if ( !(err == WOLFSSL_ERROR_WANT_READ || err == WOLFSSL_ERROR_WANT_WRITE) ) {
front->eof = 1; front->eof = 1;
} }
else { else {
@ -506,10 +496,10 @@ static int wolfSSL_BIO_MD_write(WOLFSSL_BIO* bio, const void* data, int len)
*/ */
int wolfSSL_BIO_write(WOLFSSL_BIO* bio, const void* data, int len) int wolfSSL_BIO_write(WOLFSSL_BIO* bio, const void* data, int len)
{ {
int ret = 0; int ret = 0;
int retB64 = 0; int retB64 = 0;
WOLFSSL_BIO* front = bio; WOLFSSL_BIO* front = bio;
void* frmt = NULL; void* frmt = NULL;
word32 frmtSz = 0; word32 frmtSz = 0;
WOLFSSL_ENTER("wolfSSL_BIO_write"); WOLFSSL_ENTER("wolfSSL_BIO_write");
@ -528,109 +518,114 @@ int wolfSSL_BIO_write(WOLFSSL_BIO* bio, const void* data, int len)
if (bio->method && bio->method->writeCb) { if (bio->method && bio->method->writeCb) {
ret = bio->method->writeCb(bio, (const char*)data, len); ret = bio->method->writeCb(bio, (const char*)data, len);
} }
else {
switch (bio->type) {
case WOLFSSL_BIO_BASE64:
{
#ifdef WOLFSSL_BASE64_ENCODE
word32 sz = 0;
/* check for formatting */ /* get the encoded length */
if (bio->type == WOLFSSL_BIO_BASE64) { if (bio->flags & WOLFSSL_BIO_FLAG_BASE64_NO_NL) {
#if defined(WOLFSSL_BASE64_ENCODE) if (Base64_Encode_NoNl((const byte*)data, len, NULL,
word32 sz = 0; &sz) != LENGTH_ONLY_E) {
WOLFSSL_MSG("Error with base64 get length");
if (bio->flags & WOLFSSL_BIO_FLAG_BASE64_NO_NL) { ret = WOLFSSL_FATAL_ERROR;
if (Base64_Encode_NoNl((const byte*)data, len, NULL, }
&sz) != LENGTH_ONLY_E) {
WOLFSSL_MSG("Error with base 64 get length");
ret = SSL_FATAL_ERROR;
} }
} else {
else { if (Base64_Encode((const byte*)data, len, NULL, &sz) !=
if (Base64_Encode((const byte*)data, len, NULL, &sz) != LENGTH_ONLY_E) {
LENGTH_ONLY_E) { WOLFSSL_MSG("Error with base64 get length");
WOLFSSL_MSG("Error with base 64 get length"); ret = WOLFSSL_FATAL_ERROR;
ret = SSL_FATAL_ERROR; }
} }
}
if (frmt == NULL && sz > 0 && ret != SSL_FATAL_ERROR) { /* allocate buffer for encoded output */
frmt = (void*)XMALLOC(sz, front->heap, if (frmt == NULL && sz > 0 && ret != WOLFSSL_FATAL_ERROR) {
DYNAMIC_TYPE_TMP_BUFFER); frmt = (void*)XMALLOC(sz, front->heap,
if (frmt == NULL) { DYNAMIC_TYPE_TMP_BUFFER);
WOLFSSL_MSG("Memory error"); if (frmt == NULL) {
ret = SSL_FATAL_ERROR; WOLFSSL_MSG("Memory error");
ret = WOLFSSL_FATAL_ERROR;
}
frmtSz = sz;
} }
frmtSz = sz; else if (sz > frmtSz) {
} frmt = (void*)XREALLOC(frmt, sz, front->heap,
else if (sz > frmtSz) { DYNAMIC_TYPE_TMP_BUFFER);
frmt = (void*)XREALLOC(frmt, sz, front->heap, if (frmt == NULL) {
DYNAMIC_TYPE_TMP_BUFFER); WOLFSSL_MSG("Memory error");
if (frmt == NULL) { ret = WOLFSSL_FATAL_ERROR;
WOLFSSL_MSG("Memory error"); }
ret = SSL_FATAL_ERROR; /* since frmt already existed then data should point to
new formatted buffer */
data = frmt;
len = frmtSz;
frmtSz = sz;
} }
/* since frmt already existed then data should point to knew
formatted buffer */ if (ret >= 0) {
data = frmt; /* change so that data is formatted buffer */
len = frmtSz; retB64 = wolfSSL_BIO_BASE64_write(bio, data, (word32)len,
frmtSz = sz; (byte*)frmt, &frmtSz);
data = frmt;
len = frmtSz;
}
#endif /* WOLFSSL_BASE64_ENCODE */
break;
} }
#endif /* defined(WOLFSSL_BASE64_ENCODE) */ case WOLFSSL_BIO_BIO: /* write bios */
ret = wolfSSL_BIO_BIO_write(bio, data, len);
if (ret >= 0) { break;
/* change so that data is formatted buffer */ case WOLFSSL_BIO_MEMORY:
retB64 = wolfSSL_BIO_BASE64_write(bio, data, (word32)len, ret = wolfSSL_BIO_MEMORY_write(bio, data, len);
(byte*)frmt, &frmtSz); break;
data = frmt; case WOLFSSL_BIO_FILE:
len = frmtSz; #ifndef NO_FILESYSTEM
} if (bio->ptr) {
} ret = (int)XFWRITE(data, 1, len, (XFILE)bio->ptr);
}
/* write bios */ #if !defined(USE_WINDOWS_API) && !defined(NO_WOLFSSL_DIR) && \
if (bio->type == WOLFSSL_BIO_BIO) { !defined(WOLFSSL_NUCLEUS) && !defined(WOLFSSL_NUCLEUS_1_2)
ret = wolfSSL_BIO_BIO_write(bio, data, len); else {
} ret = (int)XWRITE(bio->num, data, len);
}
if (bio->type == WOLFSSL_BIO_MEMORY) { #endif
ret = wolfSSL_BIO_MEMORY_write(bio, data, len); #endif /* !NO_FILESYSTEM */
} break;
case WOLFSSL_BIO_SSL:
#ifndef NO_FILESYSTEM #ifndef WOLFCRYPT_ONLY
if (bio && bio->type == WOLFSSL_BIO_FILE) { /* already got eof, again is error */
if (bio->ptr) if (front->eof) {
ret = (int)XFWRITE(data, 1, len, (XFILE)bio->ptr); ret = WOLFSSL_FATAL_ERROR;
#if !defined(USE_WINDOWS_API) && !defined(NO_WOLFSSL_DIR)\ }
&& !defined(WOLFSSL_NUCLEUS) && !defined(WOLFSSL_NUCLEUS_1_2) else {
else ret = wolfSSL_BIO_SSL_write(bio, data, len, front);
ret = (int)XWRITE(bio->num, data, len); }
#endif /* Rest of chain is taken care of inside call */
} goto exit_chain;
#endif #endif
break;
#ifndef WOLFCRYPT_ONLY case WOLFSSL_BIO_MD:
if (bio->type == WOLFSSL_BIO_SSL) { #ifndef WOLFCRYPT_ONLY
/* already got eof, again is error */ if (bio->next != NULL) { /* data passing through MD BIO */
if (front->eof) { ret = wolfSSL_BIO_MD_write(bio, data, len);
ret = SSL_FATAL_ERROR; }
} #endif
else { break;
ret = wolfSSL_BIO_SSL_write(bio, data, len, front); case WOLFSSL_BIO_SOCKET:
} ret = wolfIO_Send(bio->num, (char*)data, len, 0);
/* Rest of chain is taken care of inside call */ break;
break; } /* switch */
}
if (bio->type == WOLFSSL_BIO_MD) {
if (bio->next != NULL) { /* data passing through MD BIO */
ret = wolfSSL_BIO_MD_write(bio, data, len);
}
}
#endif /* WOLFCRYPT_ONLY */
if (bio->type == WOLFSSL_BIO_SOCKET) {
ret = wolfIO_Send(bio->num, (char*)data, len, 0);
} }
/* advance to the next bio in list */ /* advance to the next bio in list */
bio = bio->next; bio = bio->next;
} }
exit_chain:
/* info cb, user can override return value */ /* info cb, user can override return value */
if (front != NULL && front->infoCb != NULL) { if (front != NULL && front->infoCb != NULL) {
ret = (int)front->infoCb(front, ret = (int)front->infoCb(front,