From 692a01238e0218daea233cb45be613bfea4065e1 Mon Sep 17 00:00:00 2001 From: Marco Oliverio Date: Fri, 6 May 2022 10:09:53 +0200 Subject: [PATCH 1/3] tests: support udp in test_server_nofail() --- tests/api.c | 30 ++++++++++++++++++++++++++++-- wolfssl/test.h | 1 + 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/tests/api.c b/tests/api.c index 7edb136f5..75bbadc2a 100644 --- a/tests/api.c +++ b/tests/api.c @@ -4518,6 +4518,10 @@ static THREAD_RETURN WOLFSSL_THREAD test_server_nofail(void* args) int idx; int ret, err = 0; int sharedCtx = 0; + int doUdp = 0; + SOCKADDR_IN_T cliAddr; + socklen_t cliLen; + #if defined(OPENSSL_ALL) || defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_WPAS) size_t msg_len = 0; #endif @@ -4540,6 +4544,7 @@ static THREAD_RETURN WOLFSSL_THREAD test_server_nofail(void* args) WOLFSSL_METHOD* method = NULL; if (cbf != NULL && cbf->method != NULL) { method = cbf->method(); + } else { method = wolfSSLv23_server_method(); @@ -4574,9 +4579,24 @@ static THREAD_RETURN WOLFSSL_THREAD test_server_nofail(void* args) port = wolfSSLPort; #endif + if (cbf != NULL) + doUdp = cbf->doUdp; + /* do it here to detect failure */ - tcp_accept(&sockfd, &clientfd, opts, port, 0, 0, 0, 0, 1, 0, 0); - CloseSocket(sockfd); + tcp_accept( + &sockfd, &clientfd, opts, port, 0, doUdp, 0, 0, 1, 0, 0); + + if (doUdp) { + cliLen = sizeof(cliAddr); + + idx = (int)recvfrom(sockfd, input, sizeof(input), MSG_PEEK, + (struct sockaddr*)&cliAddr, &cliLen); + + AssertIntGT(idx, 0); + } + else { + CloseSocket(sockfd); + } wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_PEER | WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT, 0); @@ -4623,6 +4643,12 @@ static THREAD_RETURN WOLFSSL_THREAD test_server_nofail(void* args) goto done; } + if (doUdp) { + err = wolfSSL_dtls_set_peer(ssl, &cliAddr, cliLen); + if (err != WOLFSSL_SUCCESS) + goto done; + } + #ifdef WOLFSSL_SESSION_EXPORT /* only add in more complex nonblocking case with session export tests */ if (args && opts->argc > 0) { diff --git a/wolfssl/test.h b/wolfssl/test.h index a075643e6..c2ad11e4b 100644 --- a/wolfssl/test.h +++ b/wolfssl/test.h @@ -515,6 +515,7 @@ typedef struct callback_functions { unsigned char isSharedCtx:1; unsigned char loadToSSL:1; unsigned char ticNoInit:1; + unsigned char doUdp:1; } callback_functions; #if defined(WOLFSSL_SRTP) && !defined(SINGLE_THREADED) && defined(_POSIX_THREADS) From 27e73818c574fef202398b70d31244f1c5169fa4 Mon Sep 17 00:00:00 2001 From: Marco Oliverio Date: Fri, 6 May 2022 10:10:24 +0200 Subject: [PATCH 2/3] tests: run test_wolfSSL_dtls_export() over UDP instead of TCP --- tests/api.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/tests/api.c b/tests/api.c index 75bbadc2a..6579a58f8 100644 --- a/tests/api.c +++ b/tests/api.c @@ -6601,7 +6601,13 @@ static void test_wolfSSL_dtls_export(void) int msgSz = (int)XSTRLEN(msg); byte *session, *window; unsigned int sessionSz, windowSz; + +#ifndef TEST_IPV6 struct sockaddr_in peerAddr; +#else + struct sockaddr_in6 peerAddr; +#endif /* TEST_IPV6 */ + int i; @@ -6637,6 +6643,7 @@ static void test_wolfSSL_dtls_export(void) XMEMSET(&server_args, 0, sizeof(func_args)); XMEMSET(&server_cbf, 0, sizeof(callback_functions)); server_cbf.method = wolfDTLSv1_2_server_method; + server_cbf.doUdp = 1; server_args.callbacks = &server_cbf; server_args.argc = 3; /* set loop_count to 3 */ @@ -6653,15 +6660,25 @@ static void test_wolfSSL_dtls_export(void) wolfSSL_CTX_use_certificate_file(ctx, cliCertFile, SSL_FILETYPE_PEM)); AssertIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_use_PrivateKey_file(ctx, cliKeyFile, SSL_FILETYPE_PEM)); - tcp_connect(&sockfd, wolfSSLIP, server_args.signal->port, 0, 0, NULL); + tcp_connect(&sockfd, wolfSSLIP, server_args.signal->port, 1, 0, NULL); AssertNotNull(ssl = wolfSSL_new(ctx)); AssertIntEQ(wolfSSL_set_fd(ssl, sockfd), WOLFSSL_SUCCESS); /* store server information connected too */ XMEMSET(&peerAddr, 0, sizeof(peerAddr)); +#ifndef TEST_IPV6 peerAddr.sin_family = AF_INET; + AssertIntEQ(XINET_PTON(AF_INET, wolfSSLIP, &peerAddr.sin_addr),1); peerAddr.sin_port = XHTONS(server_args.signal->port); - wolfSSL_dtls_set_peer(ssl, &peerAddr, sizeof(peerAddr)); +#else + peerAddr.sin6_family = AF_INET6; + AssertIntEQ( + XINET_PTON(AF_INET6, wolfSSLIP, &peerAddr.sin6_addr),1); + peerAddr.sin6_port = XHTONS(server_args.signal->port); +#endif + + AssertIntEQ(wolfSSL_dtls_set_peer(ssl, &peerAddr, sizeof(peerAddr)), + WOLFSSL_SUCCESS); AssertIntEQ(wolfSSL_connect(ssl), WOLFSSL_SUCCESS); AssertIntEQ(wolfSSL_dtls_export(ssl, NULL, &sessionSz), 0); @@ -6680,6 +6697,8 @@ static void test_wolfSSL_dtls_export(void) AssertIntGT(wolfSSL_dtls_import(ssl, session, sessionSz), 0); AssertIntGT(wolfSSL_dtls_import(ssl, window, windowSz), 0); AssertIntEQ(wolfSSL_set_fd(ssl, sockfd), WOLFSSL_SUCCESS); + AssertIntEQ(wolfSSL_dtls_set_peer(ssl, &peerAddr, sizeof(peerAddr)), + WOLFSSL_SUCCESS); AssertIntEQ(wolfSSL_write(ssl, msg, msgSz), msgSz); AssertIntGE(wolfSSL_read(ssl, reply, sizeof(reply)), 0); AssertIntGT(wolfSSL_dtls_export_state_only(ssl, window, &windowSz), 0); From 6df65c0162328efd31cad09d5ab1820c34636ef7 Mon Sep 17 00:00:00 2001 From: Marco Oliverio Date: Thu, 5 May 2022 18:24:20 +0200 Subject: [PATCH 3/3] wolfio: dtls: fix incorrect peer matching check Ignore packet if coming from a peer of a different size *or* from a different peer. Avoid whole memcmp of sockaddr_in[6] struct because is not portable (there are optional fields in struct sockaddr_in). --- src/wolfio.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 51 insertions(+), 3 deletions(-) diff --git a/src/wolfio.c b/src/wolfio.c index 78206fb89..3881fd2bc 100644 --- a/src/wolfio.c +++ b/src/wolfio.c @@ -320,6 +320,53 @@ int EmbedSend(WOLFSSL* ssl, char *buf, int sz, void *ctx) #define SENDTO_FUNCTION sendto #define RECVFROM_FUNCTION recvfrom +static int sockAddrEqual( + SOCKADDR_S *a, XSOCKLENT aLen, SOCKADDR_S *b, XSOCKLENT bLen) +{ + if (aLen != bLen) + return 0; + + if (a->ss_family != b->ss_family) + return 0; + + if (a->ss_family == AF_INET) { + + if (aLen < sizeof(SOCKADDR_IN)) + return 0; + + if (((SOCKADDR_IN*)a)->sin_port != ((SOCKADDR_IN*)b)->sin_port) + return 0; + + if (((SOCKADDR_IN*)a)->sin_addr.s_addr != + ((SOCKADDR_IN*)b)->sin_addr.s_addr) + return 0; + + return 1; + } + +#ifdef WOLFSSL_IPV6 + if (a->ss_family == AF_INET6) { + SOCKADDR_IN6 *a6, *b6; + + if (aLen < sizeof(SOCKADDR_IN6)) + return 0; + + a6 = (SOCKADDR_IN6*)a; + b6 = (SOCKADDR_IN6*)b; + + if (((SOCKADDR_IN6*)a)->sin6_port != ((SOCKADDR_IN6*)b)->sin6_port) + return 0; + + if (XMEMCMP((void*)&a6->sin6_addr, (void*)&b6->sin6_addr, + sizeof(a6->sin6_addr)) != 0) + return 0; + + return 1; + } +#endif /* WOLFSSL_HAVE_IPV6 */ + + return 0; +} /* The receive embedded callback * return : nb bytes read, or error @@ -381,9 +428,10 @@ int EmbedReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx) return recvd; } else { - if (dtlsCtx->peer.sz > 0 - && peerSz != (XSOCKLENT)dtlsCtx->peer.sz - && XMEMCMP(&peer, dtlsCtx->peer.sa, peerSz) != 0) { + if (dtlsCtx->peer.sz > 0 && + (peerSz != (XSOCKLENT)dtlsCtx->peer.sz || + !sockAddrEqual(&peer, peerSz, (SOCKADDR_S*)dtlsCtx->peer.sa, + dtlsCtx->peer.sz))) { WOLFSSL_MSG(" Ignored packet from invalid peer"); return WOLFSSL_CBIO_ERR_WANT_READ; }