diff --git a/src/bio.c b/src/bio.c index 78ebbc4250..013c3fa0b4 100644 --- a/src/bio.c +++ b/src/bio.c @@ -3207,6 +3207,26 @@ int wolfSSL_BIO_should_retry(WOLFSSL_BIO *bio) return ret; } +int wolfSSL_BIO_should_read(WOLFSSL_BIO *bio) +{ + int ret = 0; + if (bio != NULL) { + ret = (int)(bio->flags & WOLFSSL_BIO_FLAG_READ); + } + + return ret; +} + +int wolfSSL_BIO_should_write(WOLFSSL_BIO *bio) +{ + int ret = 0; + if (bio != NULL) { + ret = (int)(bio->flags & WOLFSSL_BIO_FLAG_WRITE); + } + + return ret; +} + #endif /* OPENSSL_ALL */ #endif /* WOLFSSL_BIO_INCLUDED */ diff --git a/tests/api.c b/tests/api.c index a8c2565bf6..8b6a7dfe92 100644 --- a/tests/api.c +++ b/tests/api.c @@ -39996,6 +39996,147 @@ static int test_wolfSSL_BIO_should_retry(void) return 0; } +static int test_wolfSSL_BIO_should_read(void) +{ +#if defined(OPENSSL_ALL) && !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && \ + !defined(NO_RSA) && defined(HAVE_EXT_CACHE) && \ + defined(HAVE_IO_TESTS_DEPENDENCIES) && defined(USE_WOLFSSL_IO) + tcp_ready ready; + func_args server_args; + THREAD_TYPE serverThread; + SOCKET_T sockfd = 0; + WOLFSSL_CTX* ctx; + WOLFSSL* ssl; + char msg[64] = "hello wolfssl!"; + char reply[1024]; + int msgSz = (int)XSTRLEN(msg); + int ret; + BIO* bio; + + printf(testingFmt, "wolfSSL_BIO_should_read()"); + + XMEMSET(&server_args, 0, sizeof(func_args)); +#ifdef WOLFSSL_TIRTOS + fdOpenSession(Task_self()); +#endif + + StartTCP(); + InitTcpReady(&ready); + +#if defined(USE_WINDOWS_API) + /* use RNG to get random port if using windows */ + ready.port = GetRandomPort(); +#endif + + server_args.signal = &ready; + start_thread(test_server_nofail, &server_args, &serverThread); + wait_tcp_ready(&server_args); + + + AssertNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method())); + AssertIntEQ(WOLFSSL_SUCCESS, + wolfSSL_CTX_load_verify_locations(ctx, caCertFile, 0)); + AssertIntEQ(WOLFSSL_SUCCESS, + wolfSSL_CTX_use_certificate_file(ctx, cliCertFile, SSL_FILETYPE_PEM)); + AssertIntEQ(WOLFSSL_SUCCESS, + wolfSSL_CTX_use_PrivateKey_file(ctx, cliKeyFile, SSL_FILETYPE_PEM)); + AssertIntNE(BIO_should_read(bio), 0); + tcp_connect(&sockfd, wolfSSLIP, server_args.signal->port, 0, 0, NULL); + + + /* now perform successful connection */ + wolfSSL_SSLSetIORecv(ssl, EmbedReceive); + AssertIntEQ(BIO_write(bio, msg, msgSz), msgSz); + AssertIntNE(BIO_should_read(bio), 1); + BIO_read(bio, reply, sizeof(reply)); + AssertIntEQ(XMEMCMP(reply, "I hear you fa shizzle!", + XSTRLEN("I hear you fa shizzle!")), 0); + BIO_free(bio); + wolfSSL_CTX_free(ctx); + + join_thread(serverThread); + FreeTcpReady(&ready); + +#ifdef WOLFSSL_TIRTOS + fdOpenSession(Task_self()); +#endif + + printf(resultFmt, passed); +#endif + + return 0; +} + +static int test_wolfSSL_BIO_should_write(void) +{ +#if defined(OPENSSL_ALL) && !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && \ + !defined(NO_RSA) && defined(HAVE_EXT_CACHE) && \ + defined(HAVE_IO_TESTS_DEPENDENCIES) && defined(USE_WOLFSSL_IO) + tcp_ready ready; + func_args server_args; + THREAD_TYPE serverThread; + SOCKET_T sockfd = 0; + WOLFSSL_CTX* ctx; + WOLFSSL* ssl; + char msg[64] = "hello wolfssl!"; + char reply[1024]; + int msgSz = (int)XSTRLEN(msg); + int ret; + BIO* bio; + + printf(testingFmt, "wolfSSL_BIO_should_write()"); + + XMEMSET(&server_args, 0, sizeof(func_args)); +#ifdef WOLFSSL_TIRTOS + fdOpenSession(Task_self()); +#endif + + StartTCP(); + InitTcpReady(&ready); + +#if defined(USE_WINDOWS_API) + /* use RNG to get random port if using windows */ + ready.port = GetRandomPort(); +#endif + + server_args.signal = &ready; + start_thread(test_server_nofail, &server_args, &serverThread); + wait_tcp_ready(&server_args); + + + AssertNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method())); + AssertIntEQ(WOLFSSL_SUCCESS, + wolfSSL_CTX_load_verify_locations(ctx, caCertFile, 0)); + AssertIntEQ(WOLFSSL_SUCCESS, + wolfSSL_CTX_use_certificate_file(ctx, cliCertFile, SSL_FILETYPE_PEM)); + AssertIntEQ(WOLFSSL_SUCCESS, + wolfSSL_CTX_use_PrivateKey_file(ctx, cliKeyFile, SSL_FILETYPE_PEM)); + AssertIntNE(BIO_should_write(bio), 0); + tcp_connect(&sockfd, wolfSSLIP, server_args.signal->port, 0, 0, NULL); + + /* perform successful connection */ + wolfSSL_SSLSetIORecv(ssl, EmbedReceive); + AssertIntNE(BIO_should_write(bio), 1); + AssertIntEQ(BIO_write(bio, msg, msgSz), msgSz); + BIO_read(bio, reply, sizeof(reply)); + AssertIntEQ(XMEMCMP(reply, "I hear you fa shizzle!", + XSTRLEN("I hear you fa shizzle!")), 0); + BIO_free(bio); + wolfSSL_CTX_free(ctx); + + join_thread(serverThread); + FreeTcpReady(&ready); + +#ifdef WOLFSSL_TIRTOS + fdOpenSession(Task_self()); +#endif + + printf(resultFmt, passed); +#endif + + return 0; +} + static int test_wolfSSL_BIO_connect(void) { #if defined(OPENSSL_ALL) && defined(HAVE_IO_TESTS_DEPENDENCIES) && defined(HAVE_HTTP_CLIENT) @@ -57167,6 +57308,8 @@ TEST_CASE testCases[] = { TEST_DECL(test_wolfSSL_BIO_puts), TEST_DECL(test_wolfSSL_BIO_dump), TEST_DECL(test_wolfSSL_BIO_should_retry), + TEST_DECL(test_wolfSSL_BIO_should_read), + TEST_DECL(test_wolfSSL_BIO_should_write), TEST_DECL(test_wolfSSL_d2i_PUBKEY), TEST_DECL(test_wolfSSL_BIO_write), TEST_DECL(test_wolfSSL_BIO_connect), diff --git a/wolfssl/openssl/bio.h b/wolfssl/openssl/bio.h index 301198406b..8731708db1 100644 --- a/wolfssl/openssl/bio.h +++ b/wolfssl/openssl/bio.h @@ -79,6 +79,8 @@ #define BIO_puts wolfSSL_BIO_puts #define BIO_should_retry wolfSSL_BIO_should_retry +#define BIO_should_write wolfSSL_BIO_should_write +#define BIO_should_read wolfSSL_BIO_should_read #define BIO_TYPE_FILE WOLFSSL_BIO_FILE #define BIO_TYPE_BIO WOLFSSL_BIO_BIO diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 9d7c21d6d5..acedab7a65 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -1625,6 +1625,8 @@ WOLFSSL_API void wolfSSL_BIO_set_shutdown(WOLFSSL_BIO* bio, int shut); WOLFSSL_API int wolfSSL_BIO_get_shutdown(WOLFSSL_BIO* bio); WOLFSSL_API void wolfSSL_BIO_clear_retry_flags(WOLFSSL_BIO* bio); WOLFSSL_API int wolfSSL_BIO_should_retry(WOLFSSL_BIO *bio); +WOLFSSL_API int wolfSSL_BIO_should_read(WOLFSSL_BIO *bio); +WOLFSSL_API int wolfSSL_BIO_should_write(WOLFSSL_BIO *bio); WOLFSSL_API WOLFSSL_BIO_METHOD *wolfSSL_BIO_meth_new(int type, const char* name); WOLFSSL_API void wolfSSL_BIO_meth_free(WOLFSSL_BIO_METHOD* biom);