From 29ec038aa60a7529dba91ee69042fa000e68edf4 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Sun, 26 May 2024 18:17:55 -0500 Subject: [PATCH] checkpoint: add WOLFSSL_BIO_ADDR, wolfSSL_BIO_ADDR_new(), wolfSSL_BIO_ADDR_free(), wolfSSL_BIO_ADDR_clear(), wolfIO_SendTo(), wolfIO_RecvFrom(); fix name of wolfSSL_BIO_s_datagram(). --- src/bio.c | 107 +++++++++++++++++++++++++++++++++++--- src/internal.c | 3 ++ src/wolfio.c | 25 +++++++++ wolfssl/error-ssl.h | 2 +- wolfssl/internal.h | 54 +++++++++++++++++++ wolfssl/openssl/bio.h | 2 + wolfssl/ssl.h | 52 ++++-------------- wolfssl/wolfcrypt/types.h | 1 + wolfssl/wolfio.h | 26 +++++++++ 9 files changed, 222 insertions(+), 50 deletions(-) diff --git a/src/bio.c b/src/bio.c index 2473aea75..e391d9cf7 100644 --- a/src/bio.c +++ b/src/bio.c @@ -343,7 +343,6 @@ int wolfSSL_BIO_read(WOLFSSL_BIO* bio, void* buf, int len) #endif break; case WOLFSSL_BIO_SOCKET: - case WOLFSSL_BIO_DGRAM: #ifdef USE_WOLFSSL_IO /* BIO requires built-in socket support * (cannot be used with WOLFSSL_USER_IO) */ @@ -352,6 +351,27 @@ int wolfSSL_BIO_read(WOLFSSL_BIO* bio, void* buf, int len) ret = NOT_COMPILED_IN; #endif break; + +#ifdef WOLFSSL_HAVE_BIO_ADDR + case WOLFSSL_BIO_DGRAM: + #ifdef USE_WOLFSSL_IO + /* BIO requires built-in socket support + * (cannot be used with WOLFSSL_USER_IO) */ + if (bio->connected) + ret = wolfIO_Recv(bio->num, (char*)buf, len, 0); + else { + if (bio->peer_addr == NULL) + bio->peer_addr = wolfSSL_BIO_ADDR_new(); + else + wolfSSL_BIO_ADDR_clear(bio->peer_addr); + ret = wolfIO_RecvFrom(bio->num, bio->peer_addr, (char*)buf, len, 0); + } + #else + ret = NOT_COMPILED_IN; + #endif + break; +#endif + } /* switch */ } @@ -725,7 +745,6 @@ int wolfSSL_BIO_write(WOLFSSL_BIO* bio, const void* data, int len) #endif break; case WOLFSSL_BIO_SOCKET: - case WOLFSSL_BIO_DGRAM: #ifdef USE_WOLFSSL_IO /* BIO requires built-in socket support * (cannot be used with WOLFSSL_USER_IO) */ @@ -734,6 +753,24 @@ int wolfSSL_BIO_write(WOLFSSL_BIO* bio, const void* data, int len) ret = NOT_COMPILED_IN; #endif break; + +#ifdef WOLFSSL_HAVE_BIO_ADDR + case WOLFSSL_BIO_DGRAM: + #ifdef USE_WOLFSSL_IO + /* BIO requires built-in socket support + * (cannot be used with WOLFSSL_USER_IO) */ + if (bio->connected) + ret = wolfIO_Send(bio->num, (char*)data, len, 0); + else if (bio->peer_addr != NULL) + ret = wolfIO_SendTo(bio->num, bio->peer_addr, (char*)data, len, 0); + else + ret = SOCKET_NOT_CONNECTED_E; + #else + ret = NOT_COMPILED_IN; + #endif + break; +#endif + } /* switch */ } @@ -797,6 +834,25 @@ long wolfSSL_BIO_ctrl(WOLFSSL_BIO *bio, int cmd, long larg, void *parg) case BIO_CTRL_RESET: ret = (long)wolfSSL_BIO_reset(bio); break; + +#ifdef WOLFSSL_HAVE_BIO_ADDR + case BIO_CTRL_DGRAM_CONNECT: + case BIO_CTRL_DGRAM_SET_PEER: + if (bio->peer_addr) + wolfSSL_BIO_ADDR_free(bio->peer_addr); + bio->peer_addr = (WOLFSSL_BIO_ADDR *)parg; + ret = WOLFSSL_SUCCESS; + break; + + case BIO_CTRL_DGRAM_SET_CONNECTED: + bio->connected = (parg != NULL); + if (bio->peer_addr) + wolfSSL_BIO_ADDR_free(bio->peer_addr); + bio->peer_addr = (WOLFSSL_BIO_ADDR *)parg; + ret = WOLFSSL_SUCCESS; + break; +#endif /* WOLFSSL_HAVE_BIO_ADDR */ + default: WOLFSSL_MSG("CMD not yet implemented"); ret = WOLFSSL_FAILURE; @@ -830,8 +886,47 @@ int wolfSSL_BIO_up_ref(WOLFSSL_BIO* bio) return WOLFSSL_FAILURE; } -#endif +#ifdef WOLFSSL_HAVE_BIO_ADDR +WOLFSSL_BIO_ADDR *wolfSSL_BIO_ADDR_new(void) { + WOLFSSL_BIO_ADDR *addr = XMALLOC(sizeof(*addr), NULL, DYNAMIC_TYPE_BIO); + if (addr) + addr->sa.sa_family = AF_UNSPEC; + return addr; +} + +void wolfSSL_BIO_ADDR_free(WOLFSSL_BIO_ADDR *addr) { + XFREE(addr, NULL, DYNAMIC_TYPE_BIO); +} + +void wolfSSL_BIO_ADDR_clear(WOLFSSL_BIO_ADDR *addr) { + if (addr == NULL) + return; + XMEMSET(addr, 0, sizeof(*addr)); + addr->sa.sa_family = AF_UNSPEC; +} + +socklen_t wolfSSL_BIO_ADDR_size(const WOLFSSL_BIO_ADDR *addr) { + switch (addr->sa.sa_family) { +#ifndef WOLFSSL_NO_BIO_ADDR_IN + case AF_INET: + return sizeof(addr->sa_in); +#endif +#ifdef WOLFSSL_IPV6 + case AF_INET6: + return sizeof(addr->sa_in6); +#endif +#ifndef WOLFSSL_NO_BIO_ADDR_UN + case AF_UNIX: + return sizeof(addr->sa_un); +#endif + default: + return sizeof(*addr); + } +} +#endif /* WOLFSSL_HAVE_BIO_ADDR */ + +#endif /* OPENSSL_ALL || OPENSSL_EXTRA */ /* helper function for wolfSSL_BIO_gets * size till a newline is hit @@ -2150,12 +2245,12 @@ int wolfSSL_BIO_flush(WOLFSSL_BIO* bio) } - WOLFSSL_BIO_METHOD *wolfSSL_BIO_s_dgram(void) + WOLFSSL_BIO_METHOD *wolfSSL_BIO_s_datagram(void) { static WOLFSSL_BIO_METHOD meth = WOLFSSL_BIO_METHOD_INIT(WOLFSSL_BIO_DGRAM); - WOLFSSL_ENTER("wolfSSL_BIO_s_dgram"); + WOLFSSL_ENTER("wolfSSL_BIO_s_datagram"); return &meth; } @@ -2163,7 +2258,7 @@ int wolfSSL_BIO_flush(WOLFSSL_BIO* bio) WOLFSSL_BIO* wolfSSL_BIO_new_dgram(int fd, int closeF) { - WOLFSSL_BIO* bio = wolfSSL_BIO_new(wolfSSL_BIO_s_dgram()); + WOLFSSL_BIO* bio = wolfSSL_BIO_new(wolfSSL_BIO_s_datagram()); WOLFSSL_ENTER("wolfSSL_BIO_new_dgram"); if (bio) { diff --git a/src/internal.c b/src/internal.c index d6cce09d5..31a0f011d 100644 --- a/src/internal.c +++ b/src/internal.c @@ -25639,6 +25639,9 @@ const char* wolfSSL_ERR_reason_error_string(unsigned long e) case DUPLICATE_TLS_EXT_E: return "Duplicate TLS extension in message."; + case SOCKET_NOT_CONNECTED_E: + return "Socket has no associated peer."; + default : return "unknown error number"; } diff --git a/src/wolfio.c b/src/wolfio.c index 70e0cd8e9..95476b494 100644 --- a/src/wolfio.c +++ b/src/wolfio.c @@ -1113,6 +1113,31 @@ int wolfIO_Send(SOCKET_T sd, char *buf, int sz, int wrFlags) return sent; } +#ifdef WOLFSSL_HAVE_BIO_ADDR + +int wolfIO_RecvFrom(SOCKET_T sd, WOLFSSL_BIO_ADDR *addr, char *buf, int sz, int rdFlags) +{ + int recvd; + socklen_t addr_len = (socklen_t)sizeof(*addr); + + recvd = (int)recvfrom(sd, buf, (size_t)sz, rdFlags, addr ? &addr->sa : NULL, addr ? &addr_len : 0); + recvd = TranslateReturnCode(recvd, (int)sd); + + return recvd; +} + +int wolfIO_SendTo(SOCKET_T sd, WOLFSSL_BIO_ADDR *addr, char *buf, int sz, int wrFlags) +{ + int sent; + + sent = (int)sendto(sd, buf, (size_t)sz, wrFlags, addr ? &addr->sa : NULL, addr ? wolfSSL_BIO_ADDR_size(addr) : 0); + sent = TranslateReturnCode(sent, (int)sd); + + return sent; +} + +#endif /* WOLFSSL_HAVE_BIO_ADDR */ + #endif /* USE_WOLFSSL_IO */ diff --git a/wolfssl/error-ssl.h b/wolfssl/error-ssl.h index 724d7de00..64edf75c3 100644 --- a/wolfssl/error-ssl.h +++ b/wolfssl/error-ssl.h @@ -185,8 +185,8 @@ enum wolfSSL_ErrorCodes { DTLS_CID_ERROR = -454, /* Wrong or missing CID */ DTLS_TOO_MANY_FRAGMENTS_E = -455, /* Received too many fragments */ QUIC_WRONG_ENC_LEVEL = -456, /* QUIC data received on wrong encryption level */ - DUPLICATE_TLS_EXT_E = -457, /* Duplicate TLS extension in msg. */ + SOCKET_NOT_CONNECTED_E = -458, /* Socket has no associated peer. */ /* add strings to wolfSSL_ERR_reason_error_string in internal.c !!!!! */ /* begin negotiation parameter errors */ diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 390b21b54..12a6c5100 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -2743,6 +2743,60 @@ typedef struct WOLFSSL_DTLS_PEERSEQ { #endif } WOLFSSL_DTLS_PEERSEQ; +struct WOLFSSL_BIO { + WOLFSSL_BUF_MEM* mem_buf; + WOLFSSL_BIO_METHOD* method; + WOLFSSL_BIO* prev; /* previous in chain */ + WOLFSSL_BIO* next; /* next in chain */ + WOLFSSL_BIO* pair; /* BIO paired with */ + void* heap; /* user heap hint */ + void* ptr; /* WOLFSSL, file descriptor, MD, or mem buf */ + void* usrCtx; /* user set pointer */ + 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 */ + int wrSz; /* write buffer size (mem) */ + int wrSzReset; /* First buffer size (mem) - read ONLY data */ + int wrIdx; /* current index for write buffer */ + int rdIdx; /* current read index */ + int readRq; /* read request */ + int num; /* socket num or length */ + int eof; /* eof flag */ + int flags; + byte type; /* method type */ + byte init:1; /* bio has been initialized */ + byte shutdown:1; /* close flag */ + byte connected:1; /* connected state, for datagram BIOs -- as for + * struct WOLFSSL_DTLS_CTX, when set, sendto and + * recvfrom leave the peer_addr unchanged. */ +#ifdef WOLFSSL_HAVE_BIO_ADDR + union WOLFSSL_BIO_ADDR *peer_addr; /* for datagram BIOs, the socket address stored + * with BIO_CTRL_DGRAM_CONNECT, + * BIO_CTRL_DGRAM_SET_CONNECTED, or + * BIO_CTRL_DGRAM_SET_PEER, or stored when a + * packet was received on an unconnected BIO. */ +#endif + +#ifdef WORD64_AVAILABLE + word64 bytes_read; + word64 bytes_written; +#else + word32 bytes_read; + word32 bytes_written; +#endif + +#ifdef HAVE_EX_DATA + WOLFSSL_CRYPTO_EX_DATA ex_data; +#endif +#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) + wolfSSL_Ref ref; +#endif +}; + +#ifdef WOLFSSL_HAVE_BIO_ADDR +WOLFSSL_LOCAL socklen_t wolfSSL_BIO_ADDR_size(const WOLFSSL_BIO_ADDR *addr); +#endif #define MAX_WRITE_IV_SZ 16 /* max size of client/server write_IV */ diff --git a/wolfssl/openssl/bio.h b/wolfssl/openssl/bio.h index 8b7d287c9..72a43656e 100644 --- a/wolfssl/openssl/bio.h +++ b/wolfssl/openssl/bio.h @@ -61,6 +61,7 @@ #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_s_datagram wolfSSL_BIO_s_datagram #define BIO_s_accept wolfSSL_BIO_s_socket #define BIO_set_fd wolfSSL_BIO_set_fd #define BIO_set_close wolfSSL_BIO_set_close @@ -168,6 +169,7 @@ #define BIO_C_SET_WRITE_BUF_SIZE 136 #define BIO_C_MAKE_BIO_PAIR 138 +#define BIO_CTRL_DGRAM_CONNECT 31 #define BIO_CTRL_DGRAM_SET_CONNECTED 32 #define BIO_CTRL_DGRAM_QUERY_MTU 40 #define BIO_CTRL_DGRAM_SET_PEER 44 diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 1ab067081..d3f3a0165 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -538,47 +538,6 @@ struct WOLFSSL_BIO_METHOD { typedef long (*wolf_bio_info_cb)(WOLFSSL_BIO *bio, int event, const char *parg, int iarg, long larg, long return_value); -struct WOLFSSL_BIO { - WOLFSSL_BUF_MEM* mem_buf; - WOLFSSL_BIO_METHOD* method; - WOLFSSL_BIO* prev; /* previous in chain */ - WOLFSSL_BIO* next; /* next in chain */ - WOLFSSL_BIO* pair; /* BIO paired with */ - void* heap; /* user heap hint */ - void* ptr; /* WOLFSSL, file descriptor, MD, or mem buf */ - void* usrCtx; /* user set pointer */ - 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 */ - int wrSz; /* write buffer size (mem) */ - int wrSzReset; /* First buffer size (mem) - read ONLY data */ - int wrIdx; /* current index for write buffer */ - int rdIdx; /* current read index */ - int readRq; /* read request */ - int num; /* socket num or length */ - int eof; /* eof flag */ - int flags; - byte type; /* method type */ - byte init:1; /* bio has been initialized */ - byte shutdown:1; /* close flag */ - -#ifdef WORD64_AVAILABLE - word64 bytes_read; - word64 bytes_written; -#else - word32 bytes_read; - word32 bytes_written; -#endif - -#ifdef HAVE_EX_DATA - WOLFSSL_CRYPTO_EX_DATA ex_data; -#endif -#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) - wolfSSL_Ref ref; -#endif -}; - typedef struct WOLFSSL_COMP_METHOD { int type; /* stunnel dereference */ } WOLFSSL_COMP_METHOD; @@ -1841,7 +1800,7 @@ WOLFSSL_API WOLFSSL_BIO *wolfSSL_BIO_new_fd(int fd, int close_flag); WOLFSSL_API WOLFSSL_BIO_METHOD *wolfSSL_BIO_s_bio(void); WOLFSSL_API WOLFSSL_BIO_METHOD *wolfSSL_BIO_s_socket(void); -WOLFSSL_API WOLFSSL_BIO_METHOD *wolfSSL_BIO_s_dgram(void); +WOLFSSL_API WOLFSSL_BIO_METHOD *wolfSSL_BIO_s_datagram(void); WOLFSSL_API WOLFSSL_BIO *wolfSSL_BIO_new_connect(const char *str); WOLFSSL_API WOLFSSL_BIO *wolfSSL_BIO_new_accept(const char *port); @@ -1884,7 +1843,14 @@ WOLFSSL_API int wolfSSL_BIO_set_mem_buf(WOLFSSL_BIO* bio, WOLFSSL_BUF_MEM* bufMe int closeFlag); #endif WOLFSSL_API int wolfSSL_BIO_get_len(WOLFSSL_BIO *bio); -#endif + +#ifdef WOLFSSL_HAVE_BIO_ADDR +WOLFSSL_API WOLFSSL_BIO_ADDR *wolfSSL_BIO_ADDR_new(void); +WOLFSSL_API void wolfSSL_BIO_ADDR_free(WOLFSSL_BIO_ADDR *addr); +WOLFSSL_API void wolfSSL_BIO_ADDR_clear(WOLFSSL_BIO_ADDR *addr); +#endif /* WOLFSSL_HAVE_BIO_ADDR */ + +#endif /* !NO_BIO */ WOLFSSL_API void wolfSSL_RAND_screen(void); WOLFSSL_API const char* wolfSSL_RAND_file_name(char* fname, unsigned long len); diff --git a/wolfssl/wolfcrypt/types.h b/wolfssl/wolfcrypt/types.h index 9dd2f754e..798f794a1 100644 --- a/wolfssl/wolfcrypt/types.h +++ b/wolfssl/wolfcrypt/types.h @@ -1061,6 +1061,7 @@ typedef struct w64wrapper { DYNAMIC_TYPE_SM4_BUFFER = 99, DYNAMIC_TYPE_DEBUG_TAG = 100, DYNAMIC_TYPE_LMS = 101, + DYNAMIC_TYPE_BIO = 102, DYNAMIC_TYPE_SNIFFER_SERVER = 1000, DYNAMIC_TYPE_SNIFFER_SESSION = 1001, DYNAMIC_TYPE_SNIFFER_PB = 1002, diff --git a/wolfssl/wolfio.h b/wolfssl/wolfio.h index a4a659c4d..016174ecc 100644 --- a/wolfssl/wolfio.h +++ b/wolfssl/wolfio.h @@ -463,6 +463,32 @@ 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); +#ifdef WOLFSSL_HAVE_BIO_ADDR + +#ifndef WOLFSSL_NO_BIO_ADDR_UN +#include +#endif + +union WOLFSSL_BIO_ADDR { + struct sockaddr sa; +#ifndef WOLFSSL_NO_BIO_ADDR_IN + struct sockaddr_in sa_in; +#endif +#ifdef WOLFSSL_IPV6 + struct sockaddr_in6 sa_in6; +#endif +#ifndef WOLFSSL_NO_BIO_ADDR_UN + struct sockaddr_un sa_un; +#endif +}; + +typedef union WOLFSSL_BIO_ADDR WOLFSSL_BIO_ADDR; + +WOLFSSL_API int wolfIO_SendTo(SOCKET_T sd, WOLFSSL_BIO_ADDR *addr, char *buf, int sz, int wrFlags); +WOLFSSL_API int wolfIO_RecvFrom(SOCKET_T sd, WOLFSSL_BIO_ADDR *addr, char *buf, int sz, int rdFlags); + +#endif /* WOLFSSL_HAVE_BIO_ADDR */ + #endif /* USE_WOLFSSL_IO || HAVE_HTTP_CLIENT */ #ifndef WOLFSSL_NO_SOCK