From d72edd03b8ad04b9e08c4940d434c718560f2ef3 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Thu, 30 Jun 2022 16:58:45 +0200 Subject: [PATCH] dtls: wolfSSL_set_dtls_fd_connected wolfSSL_set_dtls_fd_connected sets the connected socket file descriptor. This descriptor should be called without addr and addr_len. --- src/ssl.c | 25 +++++++++++++++++++++++++ src/wolfio.c | 44 +++++++++++++++++++++++++++++++++++++------- wolfssl/internal.h | 3 +++ wolfssl/ssl.h | 1 + 4 files changed, 66 insertions(+), 7 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 82d7c9162..9782866fc 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -890,6 +890,25 @@ int wolfSSL_set_fd(WOLFSSL* ssl, int fd) return ret; } +#ifdef WOLFSSL_DTLS +int wolfSSL_set_dtls_fd_connected(WOLFSSL* ssl, int fd) +{ + int ret; + + WOLFSSL_ENTER("SSL_set_dtls_fd_connected"); + + if (ssl == NULL) { + return BAD_FUNC_ARG; + } + + ret = wolfSSL_set_fd(ssl, fd); + if (ret == WOLFSSL_SUCCESS) + ssl->buffers.dtlsCtx.connected = 1; + + return ret; +} +#endif + int wolfSSL_set_read_fd(WOLFSSL* ssl, int fd) { @@ -903,6 +922,7 @@ int wolfSSL_set_read_fd(WOLFSSL* ssl, int fd) ssl->IOCB_ReadCtx = &ssl->rfd; #ifdef WOLFSSL_DTLS + ssl->buffers.dtlsCtx.connected = 0; if (ssl->options.dtls) { ssl->IOCB_ReadCtx = &ssl->buffers.dtlsCtx; ssl->buffers.dtlsCtx.rfd = fd; @@ -926,6 +946,7 @@ int wolfSSL_set_write_fd(WOLFSSL* ssl, int fd) ssl->IOCB_WriteCtx = &ssl->wfd; #ifdef WOLFSSL_DTLS + ssl->buffers.dtlsCtx.connected = 0; if (ssl->options.dtls) { ssl->IOCB_WriteCtx = &ssl->buffers.dtlsCtx; ssl->buffers.dtlsCtx.wfd = fd; @@ -1188,6 +1209,8 @@ int wolfSSL_dtls_set_peer(WOLFSSL* ssl, void* peer, unsigned int peerSz) XFREE(ssl->buffers.dtlsCtx.peer.sa,ssl->heap,DYNAMIC_TYPE_SOCKADDR); ssl->buffers.dtlsCtx.peer.sa = NULL; ssl->buffers.dtlsCtx.peer.sz = 0; + ssl->buffers.dtlsCtx.peer.bufSz = 0; + ssl->buffers.dtlsCtx.userSet = 0; return WOLFSSL_SUCCESS; } @@ -1200,6 +1223,8 @@ int wolfSSL_dtls_set_peer(WOLFSSL* ssl, void* peer, unsigned int peerSz) XMEMCPY(sa, peer, peerSz); ssl->buffers.dtlsCtx.peer.sa = sa; ssl->buffers.dtlsCtx.peer.sz = peerSz; + ssl->buffers.dtlsCtx.peer.bufSz = peerSz; + ssl->buffers.dtlsCtx.userSet = 1; return WOLFSSL_SUCCESS; } return WOLFSSL_FAILURE; diff --git a/src/wolfio.c b/src/wolfio.c index 70c6217ca..d7c68fdb1 100644 --- a/src/wolfio.c +++ b/src/wolfio.c @@ -382,11 +382,35 @@ int EmbedReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx) int sd = dtlsCtx->rfd; int dtls_timeout = wolfSSL_dtls_get_current_timeout(ssl); byte doDtlsTimeout; - SOCKADDR_S peer; - XSOCKLENT peerSz = sizeof(peer); + SOCKADDR_S lclPeer; + SOCKADDR_S* peer; + XSOCKLENT peerSz; WOLFSSL_ENTER("EmbedReceiveFrom()"); + if (dtlsCtx->connected) { + peer = NULL; + } + else if (dtlsCtx->userSet) { + peer = &lclPeer; + XMEMSET(&lclPeer, 0, sizeof(lclPeer)); + peerSz = sizeof(lclPeer); + } + else { + /* Store the peer address. It is used to calculate the DTLS cookie. */ + if (dtlsCtx->peer.sa == NULL) { + dtlsCtx->peer.sa = (void*)XMALLOC(sizeof(SOCKADDR_S), + ssl->heap, DYNAMIC_TYPE_SOCKADDR); + dtlsCtx->peer.sz = 0; + if (dtlsCtx->peer.sa != NULL) + dtlsCtx->peer.bufSz = sizeof(SOCKADDR_S); + else + dtlsCtx->peer.bufSz = 0; + } + peer = dtlsCtx->peer.sa; + peerSz = dtlsCtx->peer.bufSz; + } + /* Don't use ssl->options.handShakeDone since it is true even if * we are in the process of renegotiation */ doDtlsTimeout = ssl->options.handShakeState != HANDSHAKE_DONE; @@ -443,10 +467,8 @@ int EmbedReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx) } #endif /* !NO_ASN_TIME */ - XMEMSET(&peer, 0, sizeof(peer)); - recvd = (int)DTLS_RECVFROM_FUNCTION(sd, buf, sz, ssl->rflags, - (SOCKADDR*)&peer, &peerSz); + (SOCKADDR*)peer, peer != NULL ? &peerSz : NULL); recvd = TranslateReturnCode(recvd, sd); @@ -459,15 +481,23 @@ int EmbedReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx) } return recvd; } - else { + else if (dtlsCtx->connected) { + /* Nothing to do */ + } + else if (dtlsCtx->userSet) { + /* Check we received the packet from the correct peer */ if (dtlsCtx->peer.sz > 0 && (peerSz != (XSOCKLENT)dtlsCtx->peer.sz || - !sockAddrEqual(&peer, peerSz, (SOCKADDR_S*)dtlsCtx->peer.sa, + !sockAddrEqual(peer, peerSz, (SOCKADDR_S*)dtlsCtx->peer.sa, dtlsCtx->peer.sz))) { WOLFSSL_MSG(" Ignored packet from invalid peer"); return WOLFSSL_CBIO_ERR_WANT_READ; } } + else { + /* Store size of saved address */ + dtlsCtx->peer.sz = peerSz; + } #ifndef NO_ASN_TIME ssl->dtls_start_timeout = 0; #endif /* !NO_ASN_TIME */ diff --git a/wolfssl/internal.h b/wolfssl/internal.h index efaccc767..999f0e6a7 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -2219,6 +2219,7 @@ WOLFSSL_LOCAL int DoVerifyCallback(WOLFSSL_CERT_MANAGER* cm, WOLFSSL* ssl, /* wolfSSL Sock Addr */ struct WOLFSSL_SOCKADDR { unsigned int sz; /* sockaddr size */ + unsigned int bufSz; /* sockaddr size */ void* sa; /* pointer to the sockaddr_in or sockaddr_in6 */ }; @@ -2226,6 +2227,8 @@ typedef struct WOLFSSL_DTLS_CTX { WOLFSSL_SOCKADDR peer; int rfd; int wfd; + byte userSet:1; + byte connected:1; /* Set when the rfd and wfd are connected sockets */ } WOLFSSL_DTLS_CTX; diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 56be14ad0..2915b1ef9 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -1045,6 +1045,7 @@ WOLFSSL_API int wolfSSL_CTX_set1_param(WOLFSSL_CTX* ctx, WOLFSSL_X509_VERIFY_PAR WOLFSSL_API int wolfSSL_is_server(WOLFSSL* ssl); WOLFSSL_API WOLFSSL* wolfSSL_write_dup(WOLFSSL* ssl); WOLFSSL_ABI WOLFSSL_API int wolfSSL_set_fd(WOLFSSL* ssl, int fd); +WOLFSSL_API int wolfSSL_set_dtls_fd_connected(WOLFSSL* ssl, int fd); WOLFSSL_API int wolfSSL_set_write_fd (WOLFSSL* ssl, int fd); WOLFSSL_API int wolfSSL_set_read_fd (WOLFSSL* ssl, int fd); WOLFSSL_API char* wolfSSL_get_cipher_list(int priority);