expand BIO compatibility

This commit is contained in:
Jacob Barthelmeh
2016-12-08 09:10:54 -07:00
parent a2d1db4b73
commit f7737fdc55
8 changed files with 678 additions and 141 deletions

3
.gitignore vendored
View File

@ -64,6 +64,7 @@ testsuite/testsuite
tests/unit
testsuite/testsuite.test
tests/unit.test
tests/bio_write_test.txt
testsuite/*.der
testsuite/*.pem
testsuite/*.raw
@ -188,4 +189,4 @@ wolfcrypt/user-crypto/lib/libusercrypto.*
wrapper/CSharp/x64/
# Visual Studio Code Workspace Files
*.vscode
*.vscode

450
src/bio.c
View File

@ -31,12 +31,38 @@ WOLFSSL_API long wolfSSL_BIO_ctrl(WOLFSSL_BIO *bio, int cmd, long larg, void *pa
return 1;
}
/*** TBD ***/
WOLFSSL_API long wolfSSL_BIO_ctrl_pending(WOLFSSL_BIO *b)
/* Return the number of pending bytes in read and write buffers */
size_t wolfSSL_BIO_ctrl_pending(WOLFSSL_BIO *bio)
{
(void) b;
WOLFSSL_ENTER("BIO_ctrl_pending");
return 0;
if (bio == NULL) {
return 0;
}
if (bio->ssl != NULL) {
return (long)wolfSSL_pending(bio->ssl);
}
if (bio->type == BIO_MEMORY) {
return bio->memLen;
}
/* type BIO_BIO then check paired buffer */
if (bio->type == BIO_BIO && bio->pair != NULL) {
WOLFSSL_BIO* pair = bio->pair;
if (pair->wrIdx > 0 && pair->wrIdx <= pair->rdIdx) {
/* in wrap around state where begining of buffer is being
* overwritten */
return pair->wrSz - pair->rdIdx + pair->wrIdx;
}
else {
/* simple case where has not wrapped around */
return pair->wrIdx - pair->rdIdx;
}
}
return 0;
}
@ -63,115 +89,355 @@ WOLFSSL_API long wolfSSL_BIO_int_ctrl(WOLFSSL_BIO *bp, int cmd, long larg, int i
return 0;
}
/*** TBD ***/
WOLFSSL_API long wolfSSL_BIO_set_write_buf_size(WOLFSSL_BIO *b, long size)
int wolfSSL_BIO_set_write_buf_size(WOLFSSL_BIO *bio, long size)
{
(void) b;
(void) size;
WOLFSSL_ENTER("BIO_set_write_buf_size");
WOLFSSL_ENTER("wolfSSL_BIO_set_write_buf_size");
if (bio == NULL || bio->type != BIO_BIO || size < 0) {
return SSL_FAILURE;
}
/* if already in pair then do not change size */
if (bio->pair != NULL) {
WOLFSSL_MSG("WOLFSSL_BIO is paired, free from pair before changing");
return SSL_FAILURE;
}
bio->wrSz = (int)size;
if (bio->wrSz < 0) {
WOLFSSL_MSG("Unexpected negative size value");
return SSL_FAILURE;
}
if (bio->mem != NULL) {
XFREE(bio->mem, bio->heap, DYNAMIC_TYPE_OPENSSL);
}
bio->mem = (byte*)XMALLOC(bio->wrSz, bio->heap, DYNAMIC_TYPE_OPENSSL);
if (bio->mem == NULL) {
WOLFSSL_MSG("Memory allocation error");
return SSL_FAILURE;
}
bio->wrIdx = 0;
bio->rdIdx = 0;
return SSL_SUCCESS;
}
/* Joins two BIO_BIO types. The write of b1 goes to the read of b2 and vise
* versa. Creating something similar to a two way pipe.
* Reading and writing between the two BIOs is not thread safe, they are
* expected to be used by the same thread. */
int wolfSSL_BIO_make_bio_pair(WOLFSSL_BIO *b1, WOLFSSL_BIO *b2)
{
WOLFSSL_ENTER("wolfSSL_BIO_make_bio_pair");
if (b1 == NULL || b2 == NULL) {
WOLFSSL_LEAVE("wolfSSL_BIO_make_bio_pair", BAD_FUNC_ARG);
return SSL_FAILURE;
}
/* both are expected to be of type BIO and not already paired */
if (b1->type != BIO_BIO || b2->type != BIO_BIO ||
b1->pair != NULL || b2->pair != NULL) {
WOLFSSL_MSG("Expected type BIO and not already paired");
return SSL_FAILURE;
}
/* set default write size if not already set */
if (b1->mem == NULL && wolfSSL_BIO_set_write_buf_size(b1,
WOLFSSL_BIO_SIZE) != SSL_SUCCESS) {
return SSL_FAILURE;
}
if (b2->mem == NULL && wolfSSL_BIO_set_write_buf_size(b2,
WOLFSSL_BIO_SIZE) != SSL_SUCCESS) {
return SSL_FAILURE;
}
b1->pair = b2;
b2->pair = b1;
return SSL_SUCCESS;
}
int wolfSSL_BIO_ctrl_reset_read_request(WOLFSSL_BIO *b)
{
WOLFSSL_ENTER("wolfSSL_BIO_ctrl_reset_read_request");
if (b == NULL) {
return SSL_FAILURE;
}
b->readRq = 0;
return SSL_SUCCESS;
}
/* Does not advance read index pointer */
int wolfSSL_BIO_nread0(WOLFSSL_BIO *bio, char **buf)
{
WOLFSSL_ENTER("wolfSSL_BIO_nread0");
if (bio == NULL || buf == NULL) {
WOLFSSL_MSG("NULL argument passed in");
return 0;
}
/* if paired read from pair */
if (bio->pair != NULL) {
WOLFSSL_BIO* pair = bio->pair;
/* case where have wrapped around write buffer */
*buf = (char*)pair->mem + pair->rdIdx;
if (pair->wrIdx > 0 && pair->rdIdx >= pair->wrIdx) {
return pair->wrSz - pair->rdIdx;
}
else {
return pair->wrIdx - pair->rdIdx;
}
}
return 0;
}
/*** TBD ***/
WOLFSSL_API long wolfSSL_BIO_make_bio_pair(WOLFSSL_BIO *b1, WOLFSSL_BIO *b2)
/* similar to wolfSSL_BIO_nread0 but advances the read index */
int wolfSSL_BIO_nread(WOLFSSL_BIO *bio, char **buf, int num)
{
(void) b1;
(void) b2;
WOLFSSL_ENTER("BIO_make_bio_pair");
return 0;
int sz = WOLFSSL_BIO_UNSET;
WOLFSSL_ENTER("wolfSSL_BIO_nread");
if (bio == NULL || buf == NULL) {
WOLFSSL_MSG("NULL argument passed in");
return SSL_FAILURE;
}
if (bio->pair != NULL) {
/* special case if asking to read 0 bytes */
if (num == 0) {
*buf = (char*)bio->pair->mem + bio->pair->rdIdx;
return 0;
}
/* get amount able to read and set buffer pointer */
sz = wolfSSL_BIO_nread0(bio, buf);
if (sz == 0) {
return WOLFSSL_BIO_ERROR;
}
if (num < sz) {
sz = num;
}
bio->pair->rdIdx += sz;
/* check if have read to the end of the buffer and need to reset */
if (bio->pair->rdIdx == bio->pair->wrSz) {
bio->pair->rdIdx = 0;
if (bio->pair->wrIdx == bio->pair->wrSz) {
bio->pair->wrIdx = 0;
}
}
/* check if read up to write index, if so then reset indexs */
if (bio->pair->rdIdx == bio->pair->wrIdx) {
bio->pair->rdIdx = 0;
bio->pair->wrIdx = 0;
}
}
return sz;
}
/*** TBD ***/
WOLFSSL_API int wolfSSL_BIO_ctrl_reset_read_request(WOLFSSL_BIO *b)
int wolfSSL_BIO_nwrite(WOLFSSL_BIO *bio, char **buf, int num)
{
(void) b;
WOLFSSL_ENTER("BIO_ctrl_reset_read_request");
return 0;
int sz = WOLFSSL_BIO_UNSET;
WOLFSSL_ENTER("wolfSSL_BIO_nwrite");
if (bio == NULL || buf == NULL) {
WOLFSSL_MSG("NULL argument passed in");
return 0;
}
if (bio->pair != NULL) {
if (num == 0) {
*buf = (char*)bio->mem + bio->wrIdx;
return 0;
}
if (bio->wrIdx < bio->rdIdx) {
/* if wrapped around only write up to read index. In this case
* rdIdx is always greater then wrIdx so sz will not be negative. */
sz = bio->rdIdx - bio->wrIdx;
}
else if (bio->rdIdx > 0 && bio->wrIdx == bio->rdIdx) {
return WOLFSSL_BIO_ERROR; /* no more room to write */
}
else {
/* write index is past read index so write to end of buffer */
sz = bio->wrSz - bio->wrIdx;
if (sz <= 0) {
/* either an error has occured with write index or it is at the
* end of the write buffer. */
if (bio->rdIdx == 0) {
/* no more room, nothing has been read */
return WOLFSSL_BIO_ERROR;
}
bio->wrIdx = 0;
/* check case where read index is not at 0 */
if (bio->rdIdx > 0) {
sz = bio->rdIdx; /* can write up to the read index */
}
else {
sz = bio->wrSz; /* no restriction other then buffer size */
}
}
}
if (num < sz) {
sz = num;
}
*buf = (char*)bio->mem + bio->wrIdx;
bio->wrIdx += sz;
/* if at the end of the buffer and space for wrap around then set
* write index back to 0 */
if (bio->wrIdx == bio->wrSz && bio->rdIdx > 0) {
bio->wrIdx = 0;
}
}
return sz;
}
/*** TBD ***/
WOLFSSL_API int wolfSSL_BIO_nread0(WOLFSSL_BIO *bio, char **buf)
/* Reset BIO to initial state */
int wolfSSL_BIO_reset(WOLFSSL_BIO *bio)
{
(void) bio;
(void) buf;
WOLFSSL_ENTER("BIO_nread0");
return 0;
WOLFSSL_ENTER("wolfSSL_BIO_reset");
if (bio == NULL) {
WOLFSSL_MSG("NULL argument passed in");
/* -1 is consistent failure even for FILE type */
return WOLFSSL_BIO_ERROR;
}
switch (bio->type) {
case BIO_FILE:
XREWIND(bio->file);
return 0;
case BIO_BIO:
bio->rdIdx = 0;
bio->wrIdx = 0;
return 0;
default:
WOLFSSL_MSG("Unknown BIO type needs added to reset function");
}
return WOLFSSL_BIO_ERROR;
}
/*** TBD ***/
WOLFSSL_API int wolfSSL_BIO_nread(WOLFSSL_BIO *bio, char **buf, int num)
{
(void) bio;
(void) buf;
(void) num;
WOLFSSL_ENTER("BIO_nread");
return 0;
}
/*** TBD ***/
WOLFSSL_API long wolfSSL_BIO_nwrite(WOLFSSL_BIO *bio, char **buf, int num)
{
(void) bio;
(void) buf;
(void) num;
WOLFSSL_ENTER("BIO_nwrite");
return 0;
}
/*** TBD ***/
WOLFSSL_API long wolfSSL_BIO_reset(WOLFSSL_BIO *bio)
{
(void) bio;
WOLFSSL_ENTER("BIO_reset");
return 0;
}
#if 0
#ifndef NO_FILESYSTEM
/*** TBD ***/
WOLFSSL_API long wolfSSL_BIO_set_fp(WOLFSSL_BIO *bio, XFILE fp, int c)
long wolfSSL_BIO_set_fp(WOLFSSL_BIO *bio, XFILE fp, int c)
{
(void) bio;
(void) fp;
(void) c;
WOLFSSL_ENTER("BIO_set_fp");
WOLFSSL_ENTER("wolfSSL_BIO_set_fp");
if (bio == NULL || fp == NULL) {
WOLFSSL_LEAVE("wolfSSL_BIO_set_fp", BAD_FUNC_ARG);
return SSL_FAILURE;
}
if (bio->type != BIO_FILE) {
return SSL_FAILURE;
}
bio->close = (byte)c;
bio->file = fp;
return SSL_SUCCESS;
}
long wolfSSL_BIO_get_fp(WOLFSSL_BIO *bio, XFILE* fp)
{
WOLFSSL_ENTER("wolfSSL_BIO_get_fp");
if (bio == NULL || fp == NULL) {
return SSL_FAILURE;
}
if (bio->type != BIO_FILE) {
return SSL_FAILURE;
}
*fp = bio->file;
return SSL_SUCCESS;
}
/* overwrites file */
int wolfSSL_BIO_write_filename(WOLFSSL_BIO *bio, char *name)
{
WOLFSSL_ENTER("wolfSSL_BIO_write_filename");
if (bio == NULL || name == NULL) {
return SSL_FAILURE;
}
if (bio->type == BIO_FILE) {
if (bio->file != NULL && bio->close == BIO_CLOSE) {
XFCLOSE(bio->file);
}
bio->file = XFOPEN(name, "w");
if (bio->file == NULL) {
return SSL_FAILURE;
}
bio->close = BIO_CLOSE;
return SSL_SUCCESS;
}
return SSL_FAILURE;
}
#endif /* NO_FILESYSTEM */
int wolfSSL_BIO_seek(WOLFSSL_BIO *bio, int ofs)
{
WOLFSSL_ENTER("wolfSSL_BIO_seek");
if (bio == NULL) {
return -1;
}
/* offset ofs from begining of file */
if (bio->type == BIO_FILE && XFSEEK(bio->file, ofs, SEEK_SET) < 0) {
return -1;
}
return 0;
}
/*** TBD ***/
WOLFSSL_API long wolfSSL_BIO_get_fp(WOLFSSL_BIO *bio, XFILE fp)
{
(void) bio;
(void) fp;
WOLFSSL_ENTER("BIO_get_fp");
return 0;
}
#endif
#endif
/*** TBD ***/
WOLFSSL_API long wolfSSL_BIO_seek(WOLFSSL_BIO *bio, int ofs)
long wolfSSL_BIO_set_mem_eof_return(WOLFSSL_BIO *bio, int v)
{
(void) bio;
(void) ofs;
WOLFSSL_ENTER("BIO_seek");
return 0;
}
WOLFSSL_ENTER("wolfSSL_BIO_set_mem_eof_return");
/*** TBD ***/
WOLFSSL_API long wolfSSL_BIO_write_filename(WOLFSSL_BIO *bio, char *name)
{
(void) bio;
(void) name;
WOLFSSL_ENTER("BIO_write_filename");
return 0;
}
if (bio != NULL) {
bio->eof = v;
}
/*** TBD ***/
WOLFSSL_API long wolfSSL_BIO_set_mem_eof_return(WOLFSSL_BIO *bio, int v)
{
(void) bio;
(void) v;
WOLFSSL_ENTER("BIO_set_mem_eof_return");
return 0;
}

119
src/ssl.c
View File

@ -10044,6 +10044,28 @@ int wolfSSL_set_compression(WOLFSSL* ssl)
}
WOLFSSL_BIO_METHOD* wolfSSL_BIO_s_bio(void)
{
static WOLFSSL_BIO_METHOD bio_meth;
WOLFSSL_ENTER("wolfSSL_BIO_f_bio");
bio_meth.type = BIO_BIO;
return &bio_meth;
}
WOLFSSL_BIO_METHOD* wolfSSL_BIO_s_file(void)
{
static WOLFSSL_BIO_METHOD file_meth;
WOLFSSL_ENTER("wolfSSL_BIO_f_file");
file_meth.type = BIO_FILE;
return &file_meth;
}
WOLFSSL_BIO_METHOD* wolfSSL_BIO_f_ssl(void)
{
static WOLFSSL_BIO_METHOD meth;
@ -10073,15 +10095,11 @@ int wolfSSL_set_compression(WOLFSSL* ssl)
WOLFSSL_ENTER("BIO_new_socket");
if (bio) {
XMEMSET(bio, 0, sizeof(WOLFSSL_BIO));
bio->type = BIO_SOCKET;
bio->close = (byte)closeF;
bio->eof = 0;
bio->ssl = 0;
bio->fd = sfd;
bio->prev = 0;
bio->next = 0;
bio->mem = NULL;
bio->memLen = 0;
}
return bio;
}
@ -10124,13 +10142,10 @@ int wolfSSL_set_compression(WOLFSSL* ssl)
DYNAMIC_TYPE_OPENSSL);
WOLFSSL_ENTER("BIO_new");
if (bio) {
XMEMSET(bio, 0, sizeof(WOLFSSL_BIO));
bio->type = method->type;
bio->close = 0;
bio->eof = 0;
bio->ssl = NULL;
bio->mem = NULL;
bio->memLen = 0;
bio->fd = 0;
bio->prev = NULL;
bio->next = NULL;
}
@ -10184,17 +10199,29 @@ int wolfSSL_set_compression(WOLFSSL* ssl)
int wolfSSL_BIO_free(WOLFSSL_BIO* bio)
{
/* unchain?, doesn't matter in goahead since from free all */
WOLFSSL_ENTER("BIO_free");
WOLFSSL_ENTER("wolfSSL_BIO_free");
if (bio) {
/* remove from pair by setting the paired bios pair to NULL */
if (bio->pair != NULL) {
bio->pair->pair = NULL;
}
if (bio->close) {
if (bio->ssl)
wolfSSL_free(bio->ssl);
if (bio->fd)
CloseSocket(bio->fd);
}
if (bio->type == BIO_FILE && bio->close == BIO_CLOSE) {
if (bio->file) {
XFCLOSE(bio->file);
}
}
if (bio->mem)
XFREE(bio->mem, 0, DYNAMIC_TYPE_OPENSSL);
XFREE(bio, 0, DYNAMIC_TYPE_OPENSSL);
XFREE(bio->mem, bio->heap, DYNAMIC_TYPE_OPENSSL);
XFREE(bio, bio->heap, DYNAMIC_TYPE_OPENSSL);
}
return 0;
}
@ -10212,13 +10239,37 @@ int wolfSSL_set_compression(WOLFSSL* ssl)
}
static int wolfSSL_BIO_BIO_read(WOLFSSL_BIO* bio, void* buf, int len)
{
int sz;
char* pt;
sz = wolfSSL_BIO_nread(bio, &pt, len);
if (sz > 0) {
XMEMCPY(buf, pt, sz);
}
return sz;
}
int wolfSSL_BIO_read(WOLFSSL_BIO* bio, void* buf, int len)
{
int ret;
WOLFSSL* ssl = 0;
WOLFSSL_BIO* front = bio;
WOLFSSL_ENTER("BIO_read");
WOLFSSL_ENTER("wolfSSL_BIO_read");
if (bio && bio->type == BIO_BIO) {
return wolfSSL_BIO_BIO_read(bio, buf, len);
}
if (bio && bio->type == BIO_FILE) {
return (int)XFREAD(buf, 1, len, bio->file);
}
/* already got eof, again is error */
if (front->eof)
return SSL_FATAL_ERROR;
@ -10240,13 +10291,43 @@ int wolfSSL_set_compression(WOLFSSL* ssl)
}
static int wolfSSL_BIO_BIO_write(WOLFSSL_BIO* bio, const void* data,
int len)
{
/* internal function where arguments have already been sanity checked */
int sz;
char* buf;
sz = wolfSSL_BIO_nwrite(bio, &buf, len);
/* test space for write */
if (sz <= 0) {
WOLFSSL_MSG("No room left to write");
return sz;
}
XMEMCPY(buf, data, sz);
return sz;
}
int wolfSSL_BIO_write(WOLFSSL_BIO* bio, const void* data, int len)
{
int ret;
WOLFSSL* ssl = 0;
WOLFSSL_BIO* front = bio;
WOLFSSL_ENTER("BIO_write");
WOLFSSL_ENTER("wolfSSL_BIO_write");
if (bio && bio->type == BIO_BIO) {
return wolfSSL_BIO_BIO_write(bio, data, len);
}
if (bio && bio->type == BIO_FILE) {
return (int)XFWRITE(data, 1, len, bio->file);
}
/* already got eof, again is error */
if (front->eof)
return SSL_FATAL_ERROR;
@ -10802,7 +10883,8 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md)
{
WOLFSSL_EVP_MD_CTX* ctx;
WOLFSSL_ENTER("EVP_MD_CTX_new");
ctx=XMALLOC(sizeof *ctx, NULL, DYNAMIC_TYPE_TMP_BUFFER);
ctx = (WOLFSSL_EVP_MD_CTX*)XMALLOC(sizeof *ctx, NULL,
DYNAMIC_TYPE_TMP_BUFFER);
if (ctx){
wolfSSL_EVP_MD_CTX_init(ctx);
}
@ -20145,13 +20227,6 @@ void* wolfSSL_GetRsaDecCtx(WOLFSSL* ssl)
return 0;
}
WOLFSSL_BIO_METHOD* wolfSSL_BIO_s_file(void) {
WOLFSSL_ENTER("wolfSSL_BIO_s_file");
WOLFSSL_STUB("wolfSSL_BIO_s_file");
return NULL;
}
#ifdef HAVE_ECC
const char * wolfSSL_OBJ_nid2sn(int n) {
int i;

View File

@ -1981,7 +1981,7 @@ static void test_wolfSSL_DisableExtendedMasterSecret(void)
*----------------------------------------------------------------------------*/
static void test_wolfSSL_X509_NAME_get_entry(void)
{
#ifndef NO_CERTS
#if !defined(NO_CERTS) && !defined(NO_RSA)
#if defined(OPENSSL_EXTRA) && (defined(KEEP_PEER_CERT) || defined(SESSION_CERTS)) \
&& (defined(HAVE_LIGHTY) || defined(WOLFSSL_MYSQL_COMPATIBLE))
printf(testingFmt, "wolfSSL_X509_NAME_get_entry()");
@ -2029,7 +2029,7 @@ static void test_wolfSSL_PKCS12(void)
{
/* .p12 file is encrypted with DES3 */
#if defined(OPENSSL_EXTRA) && !defined(NO_DES3) && !defined(NO_FILESYSTEM) && \
!defined(NO_ASN) && !defined(NO_PWDBASED)
!defined(NO_ASN) && !defined(NO_PWDBASED) && !defined(NO_RSA)
byte buffer[5300];
char file[] = "./certs/test-servercert.p12";
FILE *f;
@ -2529,7 +2529,7 @@ static void test_wolfSSL_PEM_PrivateKey(void)
static void test_wolfSSL_tmp_dh(void)
{
#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \
!defined(NO_FILESYSTEM) && !defined(NO_DSA)
!defined(NO_FILESYSTEM) && !defined(NO_DSA) && !defined(NO_RSA)
byte buffer[5300];
char file[] = "./certs/dsaparams.pem";
FILE *f;
@ -2826,6 +2826,176 @@ static void test_wolfSSL_PEM_read_bio(void)
}
static void test_wolfSSL_BIO(void)
{
#if defined(OPENSSL_EXTRA)
byte buffer[20];
BIO* bio1;
BIO* bio2;
BIO* bio3;
char* bufPt;
int i;
printf(testingFmt, "wolfSSL_BIO()");
for (i = 0; i < 20; i++) {
buffer[i] = i;
}
/* Creating and testing type BIO_s_bio */
AssertNotNull(bio1 = BIO_new(BIO_s_bio()));
AssertNotNull(bio2 = BIO_new(BIO_s_bio()));
AssertNotNull(bio3 = BIO_new(BIO_s_bio()));
/* read/write before set up */
AssertIntEQ(BIO_read(bio1, buffer, 2), WOLFSSL_BIO_UNSET);
AssertIntEQ(BIO_write(bio1, buffer, 2), WOLFSSL_BIO_UNSET);
AssertIntEQ(BIO_set_write_buf_size(bio1, 20), SSL_SUCCESS);
AssertIntEQ(BIO_set_write_buf_size(bio2, 8), SSL_SUCCESS);
AssertIntEQ(BIO_make_bio_pair(bio1, bio2), SSL_SUCCESS);
AssertIntEQ(BIO_nwrite(bio1, &bufPt, 10), 10);
XMEMCPY(bufPt, buffer, 10);
AssertIntEQ(BIO_write(bio1, buffer + 10, 10), 10);
/* write buffer full */
AssertIntEQ(BIO_write(bio1, buffer, 10), WOLFSSL_BIO_ERROR);
AssertIntEQ(BIO_flush(bio1), SSL_SUCCESS);
AssertIntEQ((int)BIO_ctrl_pending(bio1), 0);
/* write the other direction with pair */
AssertIntEQ((int)BIO_nwrite(bio2, &bufPt, 10), 8);
XMEMCPY(bufPt, buffer, 8);
AssertIntEQ(BIO_write(bio2, buffer, 10), WOLFSSL_BIO_ERROR);
/* try read */
AssertIntEQ((int)BIO_ctrl_pending(bio1), 8);
AssertIntEQ((int)BIO_ctrl_pending(bio2), 20);
AssertIntEQ(BIO_nread(bio2, &bufPt, (int)BIO_ctrl_pending(bio2)), 20);
for (i = 0; i < 20; i++) {
AssertIntEQ((int)bufPt[i], i);
}
AssertIntEQ(BIO_nread(bio2, &bufPt, 1), WOLFSSL_BIO_ERROR);
AssertIntEQ(BIO_nread(bio1, &bufPt, (int)BIO_ctrl_pending(bio1)), 8);
for (i = 0; i < 8; i++) {
AssertIntEQ((int)bufPt[i], i);
}
AssertIntEQ(BIO_nread(bio1, &bufPt, 1), WOLFSSL_BIO_ERROR);
/* new pair */
AssertIntEQ(BIO_make_bio_pair(bio1, bio3), SSL_FAILURE);
BIO_free(bio2); /* free bio2 and automaticly remove from pair */
AssertIntEQ(BIO_make_bio_pair(bio1, bio3), SSL_SUCCESS);
AssertIntEQ((int)BIO_ctrl_pending(bio3), 0);
AssertIntEQ(BIO_nread(bio3, &bufPt, 10), WOLFSSL_BIO_ERROR);
/* test wrap around... */
AssertIntEQ(BIO_reset(bio1), 0);
AssertIntEQ(BIO_reset(bio3), 0);
/* fill write buffer, read only small amount then write again */
AssertIntEQ(BIO_nwrite(bio1, &bufPt, 20), 20);
XMEMCPY(bufPt, buffer, 20);
AssertIntEQ(BIO_nread(bio3, &bufPt, 4), 4);
for (i = 0; i < 4; i++) {
AssertIntEQ(bufPt[i], i);
}
/* try writing over read index */
AssertIntEQ(BIO_nwrite(bio1, &bufPt, 5), 4);
XMEMSET(bufPt, 0, 4);
AssertIntEQ((int)BIO_ctrl_pending(bio3), 20);
/* read and write 0 bytes */
AssertIntEQ(BIO_nread(bio3, &bufPt, 0), 0);
AssertIntEQ(BIO_nwrite(bio1, &bufPt, 0), 0);
/* should read only to end of write buffer then need to read again */
AssertIntEQ(BIO_nread(bio3, &bufPt, 20), 16);
for (i = 0; i < 16; i++) {
AssertIntEQ(bufPt[i], buffer[4 + i]);
}
AssertIntEQ(BIO_nread(bio3, NULL, 0), SSL_FAILURE);
AssertIntEQ(BIO_nread0(bio3, &bufPt), 4);
for (i = 0; i < 4; i++) {
AssertIntEQ(bufPt[i], 0);
}
/* read index should not have advanced with nread0 */
AssertIntEQ(BIO_nread(bio3, &bufPt, 5), 4);
for (i = 0; i < 4; i++) {
AssertIntEQ(bufPt[i], 0);
}
/* write and fill up buffer checking reset of index state */
AssertIntEQ(BIO_nwrite(bio1, &bufPt, 20), 20);
XMEMCPY(bufPt, buffer, 20);
/* test reset on data in bio1 write buffer */
AssertIntEQ(BIO_reset(bio1), 0);
AssertIntEQ((int)BIO_ctrl_pending(bio3), 0);
AssertIntEQ(BIO_nread(bio3, &bufPt, 3), WOLFSSL_BIO_ERROR);
AssertIntEQ(BIO_nwrite(bio1, &bufPt, 20), 20);
XMEMCPY(bufPt, buffer, 20);
AssertIntEQ(BIO_nread(bio3, &bufPt, 6), 6);
for (i = 0; i < 6; i++) {
AssertIntEQ(bufPt[i], i);
}
/* test case of writing twice with offset read index */
AssertIntEQ(BIO_nwrite(bio1, &bufPt, 3), 3);
AssertIntEQ(BIO_nwrite(bio1, &bufPt, 4), 3); /* try overwriting */
AssertIntEQ(BIO_nwrite(bio1, &bufPt, 4), WOLFSSL_BIO_ERROR);
AssertIntEQ(BIO_nread(bio3, &bufPt, 0), 0);
AssertIntEQ(BIO_nwrite(bio1, &bufPt, 4), WOLFSSL_BIO_ERROR);
AssertIntEQ(BIO_nread(bio3, &bufPt, 1), 1);
AssertIntEQ(BIO_nwrite(bio1, &bufPt, 4), 1);
AssertIntEQ(BIO_nwrite(bio1, &bufPt, 4), WOLFSSL_BIO_ERROR);
BIO_free(bio1);
BIO_free(bio3);
/* BIOs with file pointers */
#if !defined(NO_FILESYSTEM)
{
XFILE f1;
XFILE f2;
BIO* f_bio1;
BIO* f_bio2;
unsigned char cert[300];
char testFile[] = "tests/bio_write_test.txt";
char msg[] = "bio_write_test.txt contains the first 300 bytes of certs/server-cert.pem\ncreated by tests/unit.test\n\n";
AssertNotNull(f_bio1 = BIO_new(BIO_s_file()));
AssertNotNull(f_bio2 = BIO_new(BIO_s_file()));
AssertIntEQ((int)BIO_set_mem_eof_return(f_bio1, -1), 0);
AssertIntEQ((int)BIO_set_mem_eof_return(NULL, -1), 0);
f1 = XFOPEN(svrCert, "rwb");
AssertIntEQ((int)BIO_set_fp(f_bio1, f1, BIO_CLOSE), SSL_SUCCESS);
AssertIntEQ(BIO_write_filename(f_bio2, testFile),
SSL_SUCCESS);
AssertIntEQ(BIO_read(f_bio1, cert, sizeof(cert)), sizeof(cert));
AssertIntEQ(BIO_write(f_bio2, msg, sizeof(msg)), sizeof(msg));
AssertIntEQ(BIO_write(f_bio2, cert, sizeof(cert)), sizeof(cert));
AssertIntEQ((int)BIO_get_fp(f_bio2, &f2), SSL_SUCCESS);
BIO_free(f_bio1);
BIO_free(f_bio2);
}
#endif /* !defined(NO_FILESYSTEM) */
printf(resultFmt, passed);
#endif
}
/*----------------------------------------------------------------------------*
| Main
*----------------------------------------------------------------------------*/
@ -2883,6 +3053,7 @@ void ApiTest(void)
test_wolfSSL_BN();
test_wolfSSL_set_options();
test_wolfSSL_PEM_read_bio();
test_wolfSSL_BIO();
AssertIntEQ(test_wolfSSL_Cleanup(), SSL_SUCCESS);
printf(" End API Tests\n");

View File

@ -57,7 +57,8 @@ WOLFSSL_API int wolfSSL_EVP_DecryptInit_ex(WOLFSSL_EVP_CIPHER_CTX* ctx,
WOLFSSL_API WOLFSSL_EVP_CIPHER_CTX *wolfSSL_EVP_CIPHER_CTX_new(void)
{
WOLFSSL_EVP_CIPHER_CTX *ctx=XMALLOC(sizeof *ctx, NULL, DYNAMIC_TYPE_TMP_BUFFER);
WOLFSSL_EVP_CIPHER_CTX *ctx = (WOLFSSL_EVP_CIPHER_CTX*)XMALLOC(sizeof *ctx,
NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (ctx){
WOLFSSL_ENTER("wolfSSL_EVP_CIPHER_CTX_new");
wolfSSL_EVP_CIPHER_CTX_init(ctx);

View File

@ -1249,7 +1249,9 @@ enum BIO_TYPE {
BIO_BUFFER = 1,
BIO_SOCKET = 2,
BIO_SSL = 3,
BIO_MEMORY = 4
BIO_MEMORY = 4,
BIO_BIO = 5,
BIO_FILE = 6
};
@ -1261,15 +1263,22 @@ struct WOLFSSL_BIO_METHOD {
/* wolfSSL BIO type */
struct WOLFSSL_BIO {
byte type; /* method type */
byte close; /* close flag */
byte eof; /* eof flag */
WOLFSSL* ssl; /* possible associated ssl */
byte* mem; /* memory buffer */
int memLen; /* memory buffer length */
int fd; /* possible file descriptor */
XFILE file;
WOLFSSL_BIO* prev; /* previous in chain */
WOLFSSL_BIO* next; /* next in chain */
WOLFSSL_BIO* pair; /* BIO paired with */
void* heap; /* user heap hint */
byte* mem; /* memory buffer */
int wrSz; /* write buffer size (mem) */
int wrIdx; /* current index for write buffer */
int rdIdx; /* current read index */
int readRq; /* read request */
int memLen; /* memory buffer length */
int fd; /* possible file descriptor */
int eof; /* eof flag */
byte type; /* method type */
byte close; /* close flag */
};

View File

@ -236,7 +236,11 @@ typedef WOLFSSL_X509_STORE_CTX X509_STORE_CTX;
#define BIO_new wolfSSL_BIO_new
#define BIO_free wolfSSL_BIO_free
#define BIO_free_all wolfSSL_BIO_free_all
#define BIO_nread0 wolfSSL_BIO_nread0
#define BIO_nread wolfSSL_BIO_nread
#define BIO_read wolfSSL_BIO_read
#define BIO_nwrite0 wolfSSL_BIO_nwrite0
#define BIO_nwrite wolfSSL_BIO_nwrite
#define BIO_write wolfSSL_BIO_write
#define BIO_push wolfSSL_BIO_push
#define BIO_pop wolfSSL_BIO_pop
@ -517,6 +521,8 @@ typedef WOLFSSL_X509_NAME_ENTRY X509_NAME_ENTRY;
#define BIO_get_mem_ptr wolfSSL_BIO_get_mem_ptr
#define BIO_int_ctrl wolfSSL_BIO_int_ctrl
#define BIO_reset wolfSSL_BIO_reset
#define BIO_s_file wolfSSL_BIO_s_file
#define BIO_s_bio wolfSSL_BIO_s_bio
#define BIO_s_socket wolfSSL_BIO_s_socket
#define BIO_set_fd wolfSSL_BIO_set_fd

View File

@ -519,29 +519,23 @@ WOLFSSL_API long wolfSSL_BIO_set_fd(WOLFSSL_BIO* b, int fd, int flag);
WOLFSSL_API void wolfSSL_set_bio(WOLFSSL*, WOLFSSL_BIO* rd, WOLFSSL_BIO* wr);
WOLFSSL_API int wolfSSL_add_all_algorithms(void);
WOLFSSL_API WOLFSSL_BIO_METHOD *wolfSSL_BIO_s_file(void);
WOLFSSL_API WOLFSSL_BIO_METHOD *wolfSSL_BIO_s_bio(void);
WOLFSSL_API const WOLFSSL_BIO_METHOD *wolfSSL_BIO_s_socket(void);
WOLFSSL_API long wolfSSL_BIO_ctrl(WOLFSSL_BIO *bp, int cmd, long larg, void *parg);
WOLFSSL_API long wolfSSL_BIO_ctrl_pending(WOLFSSL_BIO *b);
WOLFSSL_API long wolfSSL_BIO_int_ctrl(WOLFSSL_BIO *bp, int cmd, long larg, int iarg);
WOLFSSL_API long wolfSSL_BIO_set_write_buf_size(WOLFSSL_BIO *b, long size);
WOLFSSL_API long wolfSSL_BIO_make_bio_pair(WOLFSSL_BIO *b1, WOLFSSL_BIO *b2);
WOLFSSL_API int wolfSSL_BIO_set_write_buf_size(WOLFSSL_BIO *b, long size);
WOLFSSL_API int wolfSSL_BIO_make_bio_pair(WOLFSSL_BIO *b1, WOLFSSL_BIO *b2);
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 long wolfSSL_BIO_nwrite(WOLFSSL_BIO *bio, char **buf, int num);
WOLFSSL_API long wolfSSL_BIO_reset(WOLFSSL_BIO *bio);
WOLFSSL_API int wolfSSL_BIO_nwrite(WOLFSSL_BIO *bio, char **buf, int num);
WOLFSSL_API int wolfSSL_BIO_reset(WOLFSSL_BIO *bio);
#if 0
#ifndef NO_FILESYSTEM
WOLFSSL_API long wolfSSL_BIO_set_fp(WOLFSSL_BIO *bio, XFILE fp, int c);
WOLFSSL_API long wolfSSL_BIO_get_fp(WOLFSSL_BIO *bio, XFILE fp);
#endif
#endif
WOLFSSL_API long wolfSSL_BIO_seek(WOLFSSL_BIO *bio, int ofs);
WOLFSSL_API long wolfSSL_BIO_write_filename(WOLFSSL_BIO *bio, char *name);
WOLFSSL_API int wolfSSL_BIO_seek(WOLFSSL_BIO *bio, int ofs);
WOLFSSL_API int wolfSSL_BIO_write_filename(WOLFSSL_BIO *bio, char *name);
WOLFSSL_API long wolfSSL_BIO_set_mem_eof_return(WOLFSSL_BIO *bio, int v);
WOLFSSL_API long wolfSSL_BIO_get_mem_ptr(WOLFSSL_BIO *bio, WOLFSSL_BUF_MEM **m);
@ -938,6 +932,14 @@ enum { /* ERR Constants */
ERR_TXT_STRING = 1
};
/* bio misc */
enum {
WOLFSSL_BIO_ERROR = -1,
WOLFSSL_BIO_UNSET = -2,
WOLFSSL_BIO_SIZE = 17000 /* default BIO write size if not set */
};
WOLFSSL_API unsigned long wolfSSL_ERR_get_error_line_data(const char**, int*,
const char**, int *);
@ -1906,6 +1908,12 @@ WOLFSSL_API char* wolfSSL_ASN1_TIME_to_string(WOLFSSL_ASN1_TIME* time,
#endif /* WOLFSSL_MYSQL_COMPATIBLE */
#ifdef OPENSSL_EXTRA
#ifndef NO_FILESYSTEM
WOLFSSL_API long wolfSSL_BIO_set_fp(WOLFSSL_BIO *bio, XFILE fp, int c);
WOLFSSL_API long wolfSSL_BIO_get_fp(WOLFSSL_BIO *bio, XFILE* fp);
#endif
WOLFSSL_API unsigned long wolfSSL_ERR_peek_last_error_line(const char **file, int *line);
WOLFSSL_API long wolfSSL_ctrl(WOLFSSL* ssl, int cmd, long opt, void* pt);
WOLFSSL_API long wolfSSL_CTX_ctrl(WOLFSSL_CTX* ctx, int cmd, long opt,void* pt);
@ -1939,6 +1947,7 @@ WOLFSSL_API void wolfSSL_CTX_set_cert_store(WOLFSSL_CTX* ctx,
WOLFSSL_X509* wolfSSL_d2i_X509_bio(WOLFSSL_BIO* bio, WOLFSSL_X509** x509);
WOLFSSL_API WOLFSSL_X509_STORE* wolfSSL_CTX_get_cert_store(WOLFSSL_CTX* ctx);
WOLFSSL_API size_t wolfSSL_BIO_ctrl_pending(WOLFSSL_BIO *b);
WOLFSSL_API size_t wolfSSL_get_server_random(const WOLFSSL *ssl,
unsigned char *out, size_t outlen);
WOLFSSL_API size_t wolfSSL_get_client_random(const WOLFSSL* ssl,
@ -1965,7 +1974,6 @@ struct WOLFSSL_X509_NAME_ENTRY {
WOLFSSL_API void wolfSSL_X509_NAME_free(WOLFSSL_X509_NAME *name);
WOLFSSL_API char wolfSSL_CTX_use_certificate(WOLFSSL_CTX *ctx, WOLFSSL_X509 *x);
WOLFSSL_API int wolfSSL_BIO_read_filename(WOLFSSL_BIO *b, const char *name);
WOLFSSL_API WOLFSSL_BIO_METHOD* wolfSSL_BIO_s_file(void);
/* These are to be merged shortly */
WOLFSSL_API const char * wolfSSL_OBJ_nid2sn(int n);
WOLFSSL_API int wolfSSL_OBJ_obj2nid(const WOLFSSL_ASN1_OBJECT *o);