Implement BIO_new_accept and BIO_do_accept

This commit is contained in:
Juliusz Sosinowicz
2021-07-13 20:37:32 +02:00
parent 8b4345734e
commit 2bbd04f10f
10 changed files with 896 additions and 24 deletions

View File

@ -891,6 +891,13 @@ then
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_OPENSSH -DHAVE_EX_DATA -DWOLFSSL_BASE16"
fi
# net-snmp Build
AC_ARG_ENABLE([net-snmp],
[AS_HELP_STRING([--enable-net-snmp],[Enable net-snmp (default: disabled)])],
[ ENABLED_NETSNMP=$enableval ],
[ ENABLED_NETSNMP=no ]
)
#IP alternative name Support
AC_ARG_ENABLE([ip-alt-name],
[AS_HELP_STRING([--enable-ip-alt-name],[Enable IP subject alternative name (default: disabled)])],
@ -958,7 +965,7 @@ AC_ARG_ENABLE([opensslall],
[ ENABLED_OPENSSLALL=$enableval ],
[ ENABLED_OPENSSLALL=no ]
)
if test "$ENABLED_LIBWEBSOCKETS" = "yes" || test "$ENABLED_OPENVPN" = "yes" || test "$ENABLED_WPAS_DPP" = "yes" || test "$ENABLED_SMIME" = "yes" || test "$ENABLED_HAPROXY" = "yes" || test "$ENABLED_BIND" = "yes" || test "$ENABLED_NTP" == "yes"
if test "$ENABLED_LIBWEBSOCKETS" = "yes" || test "$ENABLED_OPENVPN" = "yes" || test "$ENABLED_WPAS_DPP" = "yes" || test "$ENABLED_SMIME" = "yes" || test "$ENABLED_HAPROXY" = "yes" || test "$ENABLED_BIND" = "yes" || test "$ENABLED_NTP" == "yes" || test "$ENABLED_NETSNMP" = "yes"
then
ENABLED_OPENSSLALL="yes"
fi
@ -1881,7 +1888,7 @@ AC_ARG_ENABLE([sessioncerts],
[ ENABLED_SESSIONCERTS=no ]
)
if test "x$ENABLED_NGINX" = "xyes" || test "x$ENABLED_OPENVPN" = "xyes" || test "x$ENABLED_LIGHTY" = "xyes"
if test "x$ENABLED_NGINX" = "xyes" || test "x$ENABLED_OPENVPN" = "xyes" || test "x$ENABLED_LIGHTY" = "xyes" || test "x$ENABLED_NETSNMP" = "xyes"
then
ENABLED_SESSIONCERTS=yes
fi
@ -3015,7 +3022,7 @@ AC_ARG_ENABLE([des3],
[ ENABLED_DES3=no ]
)
if test "$ENABLED_OPENSSH" = "yes" || test "$ENABLED_QT" = "yes" || test "$ENABLED_OPENVPN" = "yes" || test "x$ENABLED_WPAS" != "xno" || test "$ENABLED_LIBSSH2" = "yes"
if test "$ENABLED_OPENSSH" = "yes" || test "$ENABLED_QT" = "yes" || test "$ENABLED_OPENVPN" = "yes" || test "x$ENABLED_WPAS" != "xno" || test "$ENABLED_NETSNMP" = "yes" || test "$ENABLED_LIBSSH2" = "yes"
then
ENABLED_DES3="yes"
fi
@ -3122,14 +3129,6 @@ AC_ARG_ENABLE([xts],
AS_IF([test "x$ENABLED_XTS" = "xyes"],
[AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_AES_XTS -DWOLFSSL_AES_DIRECT"])
# Web Server Build
AC_ARG_ENABLE([net-snmp],
[AS_HELP_STRING([--enable-net-snmp],[Enable net-snmp (default: disabled)])],
[ ENABLED_NETSNMP=$enableval ],
[ ENABLED_NETSNMP=no ]
)
# Web Server Build
AC_ARG_ENABLE([webserver],
@ -3533,7 +3532,7 @@ AC_ARG_ENABLE([crl],
)
if test "x$ENABLED_NGINX" = "xyes" || test "x$ENABLED_HAPROXY" = "xyes" || test "x$ENABLED_OPENVPN" = "xyes" || test "x$ENABLED_WPAS" != "xno" || test "x$ENABLED_LIGHTY" = "xyes"
if test "x$ENABLED_NGINX" = "xyes" || test "x$ENABLED_HAPROXY" = "xyes" || test "x$ENABLED_OPENVPN" = "xyes" || test "x$ENABLED_WPAS" != "xno" || test "x$ENABLED_LIGHTY" = "xyes" || test "x$ENABLED_NETSNMP" = "xyes"
then
ENABLED_CRL=yes
fi
@ -4394,16 +4393,7 @@ fi
if test "$ENABLED_NETSNMP" = "yes"
then
if test "x$ENABLED_OPENSSLEXTRA" = "xno"
then
ENABLED_OPENSSLEXTRA="yes"
AM_CFLAGS="-DOPENSSL_EXTRA $AM_CFLAGS"
fi
if test "x$ENABLED_DES3" = "xno"
then
ENABLED_DES3="yes"
fi
AM_CFLAGS="$AM_CFLAGS -DHAVE_EX_DATA"
if test "x$ENABLED_AESCFB" = "xno"
then

714
src/ssl.c
View File

@ -16548,6 +16548,563 @@ int wolfSSL_set_compression(WOLFSSL* ssl)
#endif /* !NO_CERTS && (OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL) */
#ifdef OPENSSL_EXTRA
#ifndef NO_BIO
WOLFSSL_BIO_METHOD* wolfSSL_BIO_f_md(void)
{
static WOLFSSL_BIO_METHOD meth;
WOLFSSL_ENTER("wolfSSL_BIO_f_md");
meth.type = WOLFSSL_BIO_MD;
return &meth;
}
/* return the context and initialize the BIO state */
int wolfSSL_BIO_get_md_ctx(WOLFSSL_BIO *bio, WOLFSSL_EVP_MD_CTX **mdcp)
{
int ret = WOLFSSL_FAILURE;
if ((bio != NULL) && (mdcp != NULL)) {
*mdcp = (WOLFSSL_EVP_MD_CTX*)bio->ptr;
ret = WOLFSSL_SUCCESS;
}
return ret;
}
WOLFSSL_BIO_METHOD* wolfSSL_BIO_f_buffer(void)
{
static WOLFSSL_BIO_METHOD meth;
WOLFSSL_ENTER("BIO_f_buffer");
meth.type = WOLFSSL_BIO_BUFFER;
return &meth;
}
#ifndef NO_WOLFSSL_STUB
long wolfSSL_BIO_set_write_buffer_size(WOLFSSL_BIO* bio, long size)
{
/* wolfSSL has internal buffer, compatibility only */
WOLFSSL_ENTER("BIO_set_write_buffer_size");
WOLFSSL_MSG("Buffer resize failed");
WOLFSSL_STUB("BIO_set_write_buffer_size");
(void)bio;
(void) size;
/* Even though this is only a STUB at the moment many user applications
* may attempt to use this. OpenSSL documentation specifies the return
* "return 1 if the buffer was successfully resized or 0 for failure."
* since wolfSSL does not resize the buffer will always return failure
* by default due to memory concerns until this stub is promoted to
* a non-stub function */
return WOLFSSL_FAILURE; /* 0, no resize happened */
}
#endif
WOLFSSL_BIO_METHOD* wolfSSL_BIO_s_bio(void)
{
static WOLFSSL_BIO_METHOD bio_meth;
WOLFSSL_ENTER("wolfSSL_BIO_s_bio");
bio_meth.type = WOLFSSL_BIO_BIO;
return &bio_meth;
}
#ifndef NO_FILESYSTEM
WOLFSSL_BIO_METHOD* wolfSSL_BIO_s_file(void)
{
static WOLFSSL_BIO_METHOD file_meth;
WOLFSSL_ENTER("wolfSSL_BIO_s_file");
file_meth.type = WOLFSSL_BIO_FILE;
return &file_meth;
}
#endif
WOLFSSL_BIO_METHOD* wolfSSL_BIO_f_ssl(void)
{
static WOLFSSL_BIO_METHOD meth;
WOLFSSL_ENTER("wolfSSL_BIO_f_ssl");
meth.type = WOLFSSL_BIO_SSL;
return &meth;
}
WOLFSSL_BIO_METHOD *wolfSSL_BIO_s_socket(void)
{
static WOLFSSL_BIO_METHOD meth;
WOLFSSL_ENTER("wolfSSL_BIO_s_socket");
meth.type = WOLFSSL_BIO_SOCKET;
return &meth;
}
WOLFSSL_BIO* wolfSSL_BIO_new_socket(int sfd, int closeF)
{
WOLFSSL_BIO* bio = wolfSSL_BIO_new(wolfSSL_BIO_s_socket());
WOLFSSL_ENTER("BIO_new_socket");
if (bio) {
bio->type = WOLFSSL_BIO_SOCKET;
bio->shutdown = (byte)closeF;
bio->num = sfd;
}
return bio;
}
/**
* Create new socket BIO object. This is a pure TCP connection with
* no SSL or TLS protection.
* @param str IP address to connect to
* @return New BIO object or NULL on failure
*/
WOLFSSL_BIO *wolfSSL_BIO_new_connect(const char *str)
{
WOLFSSL_BIO *bio;
const char* port;
WOLFSSL_ENTER("wolfSSL_BIO_new_connect");
bio = wolfSSL_BIO_new(wolfSSL_BIO_s_socket());
if (bio) {
port = XSTRSTR(str, ":");
if (port != NULL)
bio->port = XATOI(port + 1);
else
port = str + XSTRLEN(str); /* point to null terminator */
bio->ip = (char*)XMALLOC(1 + port - str, bio->heap,
DYNAMIC_TYPE_OPENSSL);
XMEMCPY(bio->ip, str, port - str);
bio->ip[port - str] = '\0';
bio->type = WOLFSSL_BIO_SOCKET;
}
return bio;
}
/**
* Create new socket BIO object. This is a pure TCP connection with
* no SSL or TLS protection.
* @param str IP address to connect to
* @return New BIO object or NULL on failure
*/
WOLFSSL_BIO *wolfSSL_BIO_new_accept(const char *port)
{
WOLFSSL_BIO *bio;
WOLFSSL_ENTER("wolfSSL_BIO_new_accept");
bio = wolfSSL_BIO_new(wolfSSL_BIO_s_socket());
if (bio) {
bio->port = XATOI(port);
bio->type = WOLFSSL_BIO_SOCKET;
}
return bio;
}
/**
* Set the port to connect to in the BIO object
* @param b BIO object
* @param port destination port
* @return WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on failure
*/
long wolfSSL_BIO_set_conn_port(WOLFSSL_BIO *b, char* port)
{
int p;
WOLFSSL_ENTER("wolfSSL_BIO_set_conn_port");
if (!b || !port) {
WOLFSSL_ENTER("Bad parameter");
return WOLFSSL_FAILURE;
}
p = XATOI(port);
if (!p || p < 0) {
WOLFSSL_ENTER("Port parsing error");
return WOLFSSL_FAILURE;
}
b->port = (word16)p;
return WOLFSSL_SUCCESS;
}
#ifdef HAVE_HTTP_CLIENT
/**
* Attempt to connect to the destination address and port
* @param b BIO object
* @return WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on failure
*/
long wolfSSL_BIO_do_connect(WOLFSSL_BIO *b)
{
SOCKET_T sfd = SOCKET_INVALID;
WOLFSSL_ENTER("wolfSSL_BIO_do_connect");
if (!b) {
WOLFSSL_ENTER("Bad parameter");
return WOLFSSL_FAILURE;
}
while (b && b->type != WOLFSSL_BIO_SOCKET)
b = b->next;
if (!b) {
WOLFSSL_ENTER("No socket BIO in chain");
return WOLFSSL_FAILURE;
}
if (wolfIO_TcpConnect(&sfd, b->ip, b->port, 0) < 0 ) {
WOLFSSL_ENTER("wolfIO_TcpConnect error");
return WOLFSSL_FAILURE;
}
b->num = sfd;
b->shutdown = BIO_CLOSE;
return WOLFSSL_SUCCESS;
}
int wolfSSL_BIO_do_accept(WOLFSSL_BIO *b)
{
SOCKET_T sfd = SOCKET_INVALID;
WOLFSSL_ENTER("wolfSSL_BIO_do_accept");
if (!b) {
WOLFSSL_ENTER("Bad parameter");
return WOLFSSL_FAILURE;
}
while (b && b->type != WOLFSSL_BIO_SOCKET)
b = b->next;
if (!b) {
WOLFSSL_ENTER("No socket BIO in chain");
return WOLFSSL_FAILURE;
}
if (b->num == SOCKET_INVALID) {
if (wolfIO_TcpBind(&sfd, b->port) < 0) {
WOLFSSL_ENTER("wolfIO_TcpBind error");
return WOLFSSL_FAILURE;
}
b->num = sfd;
b->shutdown = BIO_CLOSE;
}
else {
WOLFSSL_BIO* new_bio;
int newfd = wolfIO_TcpAccept(b->num, NULL, NULL);
if (newfd < 0) {
WOLFSSL_ENTER("wolfIO_TcpBind error");
return WOLFSSL_FAILURE;
}
/* Create a socket BIO for using the accept'ed connection */
new_bio = wolfSSL_BIO_new_socket(newfd, BIO_CLOSE);
if (new_bio == NULL) {
WOLFSSL_ENTER("wolfSSL_BIO_new_socket error");
CloseSocket(newfd);
return WOLFSSL_FAILURE;
}
wolfSSL_BIO_set_callback(new_bio,
wolfSSL_BIO_get_callback(b));
wolfSSL_BIO_set_callback_arg(new_bio,
wolfSSL_BIO_get_callback_arg(b));
/* Push onto bio chain for user retrieval */
if (wolfSSL_BIO_push(b, new_bio) == NULL) {
WOLFSSL_ENTER("wolfSSL_BIO_push error");
CloseSocket(newfd);
return WOLFSSL_FAILURE;
}
}
return WOLFSSL_SUCCESS;
}
#endif /* HAVE_HTTP_CLIENT */
int wolfSSL_BIO_eof(WOLFSSL_BIO* b)
{
WOLFSSL_ENTER("BIO_eof");
if ((b != NULL) && (b->eof))
return 1;
return 0;
}
long wolfSSL_BIO_do_handshake(WOLFSSL_BIO *b)
{
WOLFSSL_ENTER("wolfSSL_BIO_do_handshake");
if (b == NULL) {
WOLFSSL_MSG("Bad parameter");
return WOLFSSL_FAILURE;
}
if (b->type == WOLFSSL_BIO_SSL && b->ptr != NULL) {
return wolfSSL_negotiate((WOLFSSL*)b->ptr);
}
else {
WOLFSSL_MSG("Not SSL BIO or no SSL object set");
return WOLFSSL_FAILURE;
}
}
long wolfSSL_BIO_set_ssl(WOLFSSL_BIO* b, WOLFSSL* ssl, int closeF)
{
long ret = WOLFSSL_FAILURE;
WOLFSSL_ENTER("wolfSSL_BIO_set_ssl");
if (b != NULL) {
b->ptr = ssl;
b->shutdown = (byte)closeF;
if (b->next != NULL)
wolfSSL_set_bio(ssl, b->next, b->next);
/* add to ssl for bio free if SSL_free called before/instead of free_all? */
ret = WOLFSSL_SUCCESS;
}
return ret;
}
#ifndef NO_FILESYSTEM
long wolfSSL_BIO_set_fd(WOLFSSL_BIO* b, int fd, int closeF)
{
WOLFSSL_ENTER("wolfSSL_BIO_set_fd");
if (b != NULL) {
b->num = fd;
b->shutdown = (byte)closeF;
}
return WOLFSSL_SUCCESS;
}
#endif
/* Sets the close flag */
int wolfSSL_BIO_set_close(WOLFSSL_BIO *b, long flag)
{
WOLFSSL_ENTER("wolfSSL_BIO_set_close");
if (b != NULL) {
b->shutdown = (byte)flag;
}
return WOLFSSL_SUCCESS;
}
#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
WOLFSSL_BIO* wolfSSL_BIO_new(const WOLFSSL_BIO_METHOD* method)
#else
WOLFSSL_BIO* wolfSSL_BIO_new(WOLFSSL_BIO_METHOD* method)
#endif
{
WOLFSSL_BIO* bio;
WOLFSSL_ENTER("wolfSSL_BIO_new");
if (method == NULL) {
WOLFSSL_MSG("Bad method pointer passed in");
return NULL;
}
bio = (WOLFSSL_BIO*) XMALLOC(sizeof(WOLFSSL_BIO), 0,
DYNAMIC_TYPE_OPENSSL);
if (bio) {
XMEMSET(bio, 0, sizeof(WOLFSSL_BIO));
bio->type = (byte)method->type;
#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
bio->method = (WOLFSSL_BIO_METHOD*)method;
#else
bio->method = method;
#endif
bio->shutdown = BIO_CLOSE; /* default to close things */
bio->num = SOCKET_INVALID; /* Default to invalid socket */
bio->init = 1;
if (method->type != WOLFSSL_BIO_FILE &&
method->type != WOLFSSL_BIO_SOCKET &&
method->type != WOLFSSL_BIO_MD) {
bio->mem_buf =(WOLFSSL_BUF_MEM*)XMALLOC(sizeof(WOLFSSL_BUF_MEM),
0, DYNAMIC_TYPE_OPENSSL);
if (bio->mem_buf == NULL) {
WOLFSSL_MSG("Memory error");
wolfSSL_BIO_free(bio);
return NULL;
}
bio->mem_buf->data = (char*)bio->ptr;
}
if (method->type == WOLFSSL_BIO_MD) {
bio->ptr = wolfSSL_EVP_MD_CTX_new();
if (bio->ptr == NULL) {
WOLFSSL_MSG("Memory error");
wolfSSL_BIO_free(bio);
return NULL;
}
}
/* check if is custom method */
if (method->createCb) {
method->createCb(bio);
}
}
return bio;
}
WOLFSSL_BIO* wolfSSL_BIO_new_mem_buf(const void* buf, int len)
{
WOLFSSL_BIO* bio = NULL;
if (buf == NULL) {
return bio;
}
bio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem());
if (bio == NULL) {
return bio;
}
if (len < 0) {
/* The length of the string including terminating null. */
len = (int)XSTRLEN((const char*)buf) + 1;
}
bio->num = bio->wrSz = len;
bio->ptr = (byte*)XMALLOC(len, 0, DYNAMIC_TYPE_OPENSSL);
if (bio->ptr == NULL) {
wolfSSL_BIO_free(bio);
return NULL;
}
if (bio->mem_buf != NULL) {
bio->mem_buf->data = (char*)bio->ptr;
bio->mem_buf->length = bio->num;
}
XMEMCPY(bio->ptr, buf, len);
return bio;
}
/*
* Note : If the flag BIO_NOCLOSE is set then freeing memory buffers is up
* to the application.
* Returns 1 on success, 0 on failure
*/
int wolfSSL_BIO_free(WOLFSSL_BIO* bio)
{
int ret;
/* unchain?, doesn't matter in goahead since from free all */
WOLFSSL_ENTER("wolfSSL_BIO_free");
if (bio) {
#ifdef HAVE_EX_DATA_CLEANUP_HOOKS
wolfSSL_CRYPTO_cleanup_ex_data(&bio->ex_data);
#endif
if (bio->infoCb) {
/* info callback is called before free */
ret = (int)bio->infoCb(bio, WOLFSSL_BIO_CB_FREE, NULL, 0, 0, 1);
if (ret <= 0) {
return ret;
}
}
/* call custom set free callback */
if (bio->method && bio->method->freeCb) {
bio->method->freeCb(bio);
}
/* remove from pair by setting the paired bios pair to NULL */
if (bio->pair != NULL) {
bio->pair->pair = NULL;
}
if (bio->ip != NULL) {
XFREE(bio->ip, bio->heap, DYNAMIC_TYPE_OPENSSL);
}
if (bio->shutdown) {
if (bio->type == WOLFSSL_BIO_SSL && bio->ptr)
wolfSSL_free((WOLFSSL*)bio->ptr);
#ifdef CloseSocket
if (bio->type == WOLFSSL_BIO_SOCKET && bio->num)
CloseSocket(bio->num);
#endif
}
#ifndef NO_FILESYSTEM
if (bio->type == WOLFSSL_BIO_FILE && bio->shutdown == BIO_CLOSE) {
if (bio->ptr) {
XFCLOSE((XFILE)bio->ptr);
}
#if !defined(USE_WINDOWS_API) && !defined(NO_WOLFSSL_DIR)\
&& !defined(WOLFSSL_NUCLEUS) && !defined(WOLFSSL_NUCLEUS_1_2)
else if (bio->num != SOCKET_INVALID) {
XCLOSE(bio->num);
}
#endif
}
#endif
if (bio->shutdown != BIO_NOCLOSE) {
if (bio->type == WOLFSSL_BIO_MEMORY && bio->ptr != NULL) {
if (bio->mem_buf != NULL) {
if (bio->mem_buf->data != (char*)bio->ptr) {
XFREE(bio->ptr, bio->heap, DYNAMIC_TYPE_OPENSSL);
bio->ptr = NULL;
}
}
else {
XFREE(bio->ptr, bio->heap, DYNAMIC_TYPE_OPENSSL);
bio->ptr = NULL;
}
}
if (bio->mem_buf != NULL) {
wolfSSL_BUF_MEM_free(bio->mem_buf);
bio->mem_buf = NULL;
}
}
if (bio->type == WOLFSSL_BIO_MD) {
wolfSSL_EVP_MD_CTX_free((WOLFSSL_EVP_MD_CTX*)bio->ptr);
}
XFREE(bio, 0, DYNAMIC_TYPE_OPENSSL);
return WOLFSSL_SUCCESS;
}
return WOLFSSL_FAILURE;
}
/* like BIO_free, but no return value */
void wolfSSL_BIO_vfree(WOLFSSL_BIO* bio)
{
wolfSSL_BIO_free(bio);
}
void wolfSSL_BIO_free_all(WOLFSSL_BIO* bio)
{
WOLFSSL_ENTER("BIO_free_all");
while (bio) {
WOLFSSL_BIO* next = bio->next;
wolfSSL_BIO_free(bio);
bio = next;
}
}
WOLFSSL_BIO* wolfSSL_BIO_push(WOLFSSL_BIO* top, WOLFSSL_BIO* append)
{
WOLFSSL_ENTER("BIO_push");
top->next = append;
append->prev = top;
/* SSL BIO's should use the next object in the chain for IO */
if (top->type == WOLFSSL_BIO_SSL && top->ptr)
wolfSSL_set_bio((WOLFSSL*)top->ptr, append, append);
return top;
}
#endif /* !NO_BIO */
#endif /* OPENSSL_EXTRA */
#ifdef WOLFSSL_ENCRYPTED_KEYS
void wolfSSL_CTX_set_default_passwd_cb_userdata(WOLFSSL_CTX* ctx,
@ -23849,6 +24406,163 @@ void wolfSSL_MD4_Final(unsigned char* digest, WOLFSSL_MD4_CTX* md4)
#endif /* NO_MD4 */
#ifndef NO_BIO
/* Removes a WOLFSSL_BIO struct from the WOLFSSL_BIO linked list.
*
* bio is the WOLFSSL_BIO struct in the list and removed.
*
* The return WOLFSSL_BIO struct is the next WOLFSSL_BIO in the list or NULL if
* there is none.
*/
WOLFSSL_BIO* wolfSSL_BIO_pop(WOLFSSL_BIO* bio)
{
if (bio == NULL) {
WOLFSSL_MSG("Bad argument passed in");
return NULL;
}
if (bio->prev != NULL) {
bio->prev->next = bio->next;
}
if (bio->next != NULL) {
bio->next->prev = bio->prev;
}
return bio->next;
}
WOLFSSL_BIO_METHOD* wolfSSL_BIO_s_mem(void)
{
static WOLFSSL_BIO_METHOD meth;
WOLFSSL_ENTER("wolfSSL_BIO_s_mem");
meth.type = WOLFSSL_BIO_MEMORY;
return &meth;
}
WOLFSSL_BIO_METHOD* wolfSSL_BIO_f_base64(void)
{
static WOLFSSL_BIO_METHOD meth;
WOLFSSL_ENTER("wolfSSL_BIO_f_base64");
meth.type = WOLFSSL_BIO_BASE64;
return &meth;
}
/* Set the flag for the bio.
*
* bio the structure to set the flag in
* flags the flag to use
*/
void wolfSSL_BIO_set_flags(WOLFSSL_BIO* bio, int flags)
{
WOLFSSL_ENTER("wolfSSL_BIO_set_flags");
if (bio != NULL) {
bio->flags |= flags;
}
}
void wolfSSL_BIO_clear_flags(WOLFSSL_BIO *bio, int flags)
{
WOLFSSL_ENTER("wolfSSL_BIO_clear_flags");
if (bio != NULL) {
bio->flags &= ~flags;
}
}
/* Set ex_data for WOLFSSL_BIO
*
* bio : BIO structure to set ex_data in
* idx : Index of ex_data to set
* data : Data to set in ex_data
*
* Returns WOLFSSL_SUCCESS on success or WOLFSSL_FAILURE on failure
*/
int wolfSSL_BIO_set_ex_data(WOLFSSL_BIO *bio, int idx, void *data)
{
WOLFSSL_ENTER("wolfSSL_BIO_set_ex_data");
#ifdef HAVE_EX_DATA
if (bio != NULL && idx < MAX_EX_DATA) {
return wolfSSL_CRYPTO_set_ex_data(&bio->ex_data, idx, data);
}
#else
(void)bio;
(void)idx;
(void)data;
#endif
return WOLFSSL_FAILURE;
}
int wolfSSL_BIO_get_fd(WOLFSSL_BIO *bio, int* fd)
{
WOLFSSL_ENTER("wolfSSL_BIO_get_fd");
if (bio != NULL) {
if (fd != NULL)
*fd = bio->num;
return bio->num;
}
return SOCKET_INVALID;
}
#ifdef HAVE_EX_DATA_CLEANUP_HOOKS
/* Set ex_data for WOLFSSL_BIO
*
* bio : BIO structure to set ex_data in
* idx : Index of ex_data to set
* data : Data to set in ex_data
* cleanup_routine : Function pointer to clean up data
*
* Returns WOLFSSL_SUCCESS on success or WOLFSSL_FAILURE on failure
*/
int wolfSSL_BIO_set_ex_data_with_cleanup(
WOLFSSL_BIO *bio,
int idx,
void *data,
wolfSSL_ex_data_cleanup_routine_t cleanup_routine)
{
WOLFSSL_ENTER("wolfSSL_BIO_set_ex_data_with_cleanup");
if (bio != NULL && idx < MAX_EX_DATA) {
return wolfSSL_CRYPTO_set_ex_data_with_cleanup(&bio->ex_data, idx, data,
cleanup_routine);
}
return WOLFSSL_FAILURE;
}
#endif /* HAVE_EX_DATA_CLEANUP_HOOKS */
/* Get ex_data in WOLFSSL_BIO at given index
*
* bio : BIO structure to get ex_data from
* idx : Index of ex_data to get data from
*
* Returns void pointer to ex_data on success or NULL on failure
*/
void *wolfSSL_BIO_get_ex_data(WOLFSSL_BIO *bio, int idx)
{
WOLFSSL_ENTER("wolfSSL_BIO_get_ex_data");
#ifdef HAVE_EX_DATA
if (bio != NULL && idx < MAX_EX_DATA && idx >= 0) {
return wolfSSL_CRYPTO_get_ex_data(&bio->ex_data, idx);
}
#else
(void)bio;
(void)idx;
#endif
return NULL;
}
#endif /* !NO_BIO */
#ifndef NO_WOLFSSL_STUB
void wolfSSL_RAND_screen(void)
{

View File

@ -862,6 +862,67 @@ int wolfIO_TcpConnect(SOCKET_T* sockfd, const char* ip, word16 port, int to_sec)
#endif /* HAVE_SOCKADDR */
}
int wolfIO_TcpBind(SOCKET_T* sockfd, word16 port)
{
#ifdef HAVE_SOCKADDR
SOCKADDR_S addr;
int sockaddr_len = sizeof(SOCKADDR_IN);
SOCKADDR_IN *sin = (SOCKADDR_IN *)&addr;
if (sockfd == NULL || port < 1) {
return -1;
}
XMEMSET(&addr, 0, sizeof(addr));
sin->sin_family = AF_INET;
sin->sin_addr.s_addr = INADDR_ANY;
sin->sin_port = XHTONS(port);
*sockfd = (SOCKET_T)socket(AF_INET, SOCK_STREAM, 0);
#if !defined(USE_WINDOWS_API) && !defined(WOLFSSL_MDK_ARM)\
&& !defined(WOLFSSL_KEIL_TCP_NET) && !defined(WOLFSSL_ZEPHYR)
{
int optval = 1;
socklen_t optlen = sizeof(optval);
if (setsockopt(*sockfd, SOL_SOCKET, SO_REUSEADDR, &optval, optlen) < 0) {
WOLFSSL_MSG("setsockopt SO_REUSEADDR failed");
CloseSocket(*sockfd);
*sockfd = SOCKET_INVALID;
return -1;
}
}
#endif
if (bind(*sockfd, (SOCKADDR *)sin, sockaddr_len) != 0) {
WOLFSSL_MSG("tcp bind failed");
CloseSocket(*sockfd);
*sockfd = SOCKET_INVALID;
return -1;
}
if (listen(*sockfd, SOMAXCONN) != 0) {
WOLFSSL_MSG("tcp listen failed");
CloseSocket(*sockfd);
*sockfd = SOCKET_INVALID;
return -1;
}
return 0;
#else
(void)sockfd;
(void)port;
return -1;
#endif /* HAVE_SOCKADDR */
}
#ifdef HAVE_SOCKADDR
int wolfIO_TcpAccept(SOCKET_T sockfd, SOCKADDR* peer_addr, socklen_t* peer_len)
{
return accept(sockfd, peer_addr, peer_len);
}
#endif /* HAVE_SOCKADDR */
#ifndef HTTP_SCRATCH_BUFFER_SIZE
#define HTTP_SCRATCH_BUFFER_SIZE 512
#endif

View File

@ -35193,6 +35193,76 @@ static void test_wolfSSL_BIO_connect(void)
#endif
}
#if defined(OPENSSL_ALL) && defined(HAVE_IO_TESTS_DEPENDENCIES) && defined(HAVE_HTTP_CLIENT)
static THREAD_RETURN WOLFSSL_THREAD test_wolfSSL_BIO_accept_client(void* args)
{
BIO* clientBio;
SSL* sslClient;
SSL_CTX* ctx;
char connectAddr[20]; /* IP + port */;
(void)args;
AssertIntGT(snprintf(connectAddr, sizeof(connectAddr), "%s:%d", wolfSSLIP, wolfSSLPort), 0);
AssertNotNull(clientBio = BIO_new_connect(connectAddr));
AssertIntEQ(BIO_do_connect(clientBio), 1);
AssertNotNull(ctx = SSL_CTX_new(SSLv23_method()));
AssertNotNull(sslClient = SSL_new(ctx));
AssertIntEQ(wolfSSL_CTX_load_verify_locations(ctx, caCertFile, 0), WOLFSSL_SUCCESS);
SSL_set_bio(sslClient, clientBio, clientBio);
AssertIntEQ(SSL_connect(sslClient), 1);
SSL_free(sslClient);
SSL_CTX_free(ctx);
return 0;
}
#endif
static void test_wolfSSL_BIO_accept(void)
{
#if defined(OPENSSL_ALL) && defined(HAVE_IO_TESTS_DEPENDENCIES) && defined(HAVE_HTTP_CLIENT)
BIO* serverBindBio;
BIO* serverAcceptBio;
SSL* sslServer;
SSL_CTX* ctx;
func_args args;
THREAD_TYPE thread;
char port[10]; /* 10 bytes should be enough to store the string
* representation of the port */
printf(testingFmt, "wolfSSL_BIO_new_accept()");
AssertIntGT(snprintf(port, sizeof(port), "%d", wolfSSLPort), 0);
AssertNotNull(serverBindBio = BIO_new_accept(port));
/* First BIO_do_accept binds the port */
AssertIntEQ(BIO_do_accept(serverBindBio), 1);
XMEMSET(&args, 0, sizeof(func_args));
start_thread(test_wolfSSL_BIO_accept_client, &args, &thread);
AssertIntEQ(BIO_do_accept(serverBindBio), 1);
/* Let's plug it into SSL to test */
AssertNotNull(ctx = SSL_CTX_new(SSLv23_method()));
AssertIntEQ(wolfSSL_CTX_use_certificate_file(ctx, svrCertFile, SSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
AssertIntEQ(wolfSSL_CTX_use_PrivateKey_file(ctx, svrKeyFile, SSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
AssertNotNull(sslServer = SSL_new(ctx));
AssertNotNull(serverAcceptBio = BIO_pop(serverBindBio));
SSL_set_bio(sslServer, serverAcceptBio, serverAcceptBio);
AssertIntEQ(SSL_accept(sslServer), 1);
join_thread(thread);
BIO_free(serverBindBio);
SSL_free(sslServer);
SSL_CTX_free(ctx);
printf(resultFmt, passed);
#endif
}
static void test_wolfSSL_BIO_write(void)
{
#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_BASE64_ENCODE)
@ -46841,6 +46911,7 @@ void ApiTest(void)
test_wolfSSL_d2i_PUBKEY();
test_wolfSSL_BIO_write();
test_wolfSSL_BIO_connect();
test_wolfSSL_BIO_accept();
test_wolfSSL_BIO_printf();
test_wolfSSL_BIO_f_md();
#endif

View File

@ -109,6 +109,8 @@
#define BIO_get_shutdown wolfSSL_BIO_get_shutdown
#define BIO_set_shutdown wolfSSL_BIO_set_shutdown
#define BIO_get_fd wolfSSL_BIO_get_fd
#define BIO_clear_flags wolfSSL_BIO_clear_flags
#define BIO_set_ex_data wolfSSL_BIO_set_ex_data
#define BIO_get_ex_data wolfSSL_BIO_get_ex_data

View File

@ -37,6 +37,8 @@
#define RSA_R_UNKNOWN_PADDING_TYPE RSA_PAD_E
#define EC_R_BUFFER_TOO_SMALL BUFFER_E
#define ERR_TXT_MALLOCED 1
/* SSL function codes */
#define RSA_F_RSA_OSSL_PRIVATE_ENCRYPT 1
#define SSL_F_SSL_CTX_USE_CERTIFICATE_FILE 2

View File

@ -715,8 +715,10 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_
#define BIO_f_ssl wolfSSL_BIO_f_ssl
#define BIO_new_socket wolfSSL_BIO_new_socket
#define BIO_new_connect wolfSSL_BIO_new_connect
#define BIO_new_accept wolfSSL_BIO_new_accept
#define BIO_set_conn_port wolfSSL_BIO_set_conn_port
#define BIO_do_connect wolfSSL_BIO_do_connect
#define BIO_do_accept wolfSSL_BIO_do_accept
#define BIO_do_handshake wolfSSL_BIO_do_handshake
#define SSL_set_bio wolfSSL_set_bio
#define BIO_set_ssl wolfSSL_BIO_set_ssl

View File

@ -1,5 +1,29 @@
/* x509.h
*
* Copyright (C) 2006-2021 wolfSSL Inc.
*
* This file is part of wolfSSL.
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
/* x509.h for openssl */
#ifndef WOLFSSL_OPENSSL_509_H_
#define WOLFSSL_OPENSSL_509_H_
#include <wolfssl/openssl/ssl.h>
#include <wolfssl/openssl/crypto.h>
#include <wolfssl/openssl/dh.h>
@ -42,3 +66,5 @@
#define XN_FLAG_FN_ALIGN (1 << 25)
#define XN_FLAG_MULTILINE 0xFFFF
#endif /* WOLFSSL_OPENSSL_509_H_ */

View File

@ -422,7 +422,6 @@ struct WOLFSSL_X509_PUBKEY {
int pubKeyOID;
};
enum BIO_TYPE {
WOLFSSL_BIO_BUFFER = 1,
WOLFSSL_BIO_SOCKET = 2,
@ -500,7 +499,7 @@ struct WOLFSSL_BIO {
void* heap; /* user heap hint */
void* ptr; /* WOLFSSL, file descriptor, MD, or mem buf */
void* usrCtx; /* user set pointer */
const char* ip; /* IP address for wolfIO_TcpConnect */
char* ip; /* IP address for wolfIO_TcpConnect */
word16 port; /* Port for wolfIO_TcpConnect */
char* infoArg; /* BIO callback argument */
wolf_bio_info_cb infoCb; /* BIO callback */
@ -1444,6 +1443,7 @@ WOLFSSL_API WOLFSSL_BIO_METHOD* wolfSSL_BIO_s_mem(void);
WOLFSSL_API WOLFSSL_BIO_METHOD* wolfSSL_BIO_f_base64(void);
WOLFSSL_API void wolfSSL_BIO_set_flags(WOLFSSL_BIO*, int);
WOLFSSL_API void wolfSSL_BIO_clear_flags(WOLFSSL_BIO *bio, int flags);
WOLFSSL_API int wolfSSL_BIO_get_fd(WOLFSSL_BIO *bio, int* fd);
WOLFSSL_API int wolfSSL_BIO_set_ex_data(WOLFSSL_BIO *bio, int idx, void *data);
#ifdef HAVE_EX_DATA_CLEANUP_HOOKS
WOLFSSL_API int wolfSSL_BIO_set_ex_data_with_cleanup(
@ -1492,8 +1492,10 @@ WOLFSSL_API WOLFSSL_BIO_METHOD *wolfSSL_BIO_s_bio(void);
WOLFSSL_API WOLFSSL_BIO_METHOD *wolfSSL_BIO_s_socket(void);
WOLFSSL_API WOLFSSL_BIO *wolfSSL_BIO_new_connect(const char *str);
WOLFSSL_API WOLFSSL_BIO *wolfSSL_BIO_new_accept(const char *port);
WOLFSSL_API long wolfSSL_BIO_set_conn_port(WOLFSSL_BIO *b, char* port);
WOLFSSL_API long wolfSSL_BIO_do_connect(WOLFSSL_BIO *b);
WOLFSSL_API int wolfSSL_BIO_do_accept(WOLFSSL_BIO *b);
WOLFSSL_API long wolfSSL_BIO_do_handshake(WOLFSSL_BIO *b);

View File

@ -373,6 +373,8 @@
#endif
WOLFSSL_API int wolfIO_TcpConnect(SOCKET_T* sockfd, const char* ip,
unsigned short port, int to_sec);
WOLFSSL_API int wolfIO_TcpAccept(SOCKET_T sockfd, SOCKADDR* peer_addr, socklen_t* peer_len);
WOLFSSL_API int wolfIO_TcpBind(SOCKET_T* sockfd, word16 port);
WOLFSSL_API int wolfIO_Send(SOCKET_T sd, char *buf, int sz, int wrFlags);
WOLFSSL_API int wolfIO_Recv(SOCKET_T sd, char *buf, int sz, int rdFlags);