mirror of https://github.com/wolfSSL/wolfssl.git
Merge pull request #6087 from rizlik/embed_recv_from_fix_peer
dtls: improve different peer recvfrom and better error reporting on ipv6pull/6448/head
commit
1218cfb7f2
215
src/wolfio.c
215
src/wolfio.c
|
@ -51,6 +51,14 @@ Possible IO enable options:
|
|||
* HAVE_HTTP_CLIENT: Enables HTTP client API's default: off
|
||||
(unless HAVE_OCSP or HAVE_CRL_IO defined)
|
||||
* HAVE_IO_TIMEOUT: Enables support for connect timeout default: off
|
||||
*
|
||||
* DTLS_RECEIVEFROM_NO_TIMEOUT_ON_INVALID_PEER: This flag has effect only if
|
||||
* ASN_NO_TIME is enabled. If enabled invalid peers messages are ignored
|
||||
* indefinetely. If not enabled EmbedReceiveFrom will return timeout after
|
||||
* DTLS_RECEIVEFROM_MAX_INVALID_PEER number of packets from invalid peers. When
|
||||
* enabled, without a timer, EmbedReceivefrom can't check if the timeout is
|
||||
* expired and it may never return under a continous flow of invalid packets.
|
||||
* default: off
|
||||
*/
|
||||
|
||||
|
||||
|
@ -59,6 +67,11 @@ Possible IO enable options:
|
|||
but they'll still need SetCallback xxx() at end of file
|
||||
*/
|
||||
|
||||
#if defined(NO_ASN_TIME) && !defined(DTLS_RECEIVEFROM_NO_TIMEOUT_ON_INVALID_PEER) \
|
||||
&& !defined(DTLS_RECEIVEFROM_MAX_INVALID_PEER)
|
||||
#define DTLS_RECEIVEFROM_MAX_INVALID_PEER 10
|
||||
#endif
|
||||
|
||||
#if defined(USE_WOLFSSL_IO) || defined(HAVE_HTTP_CLIENT)
|
||||
|
||||
/* Translates return codes returned from
|
||||
|
@ -333,7 +346,7 @@ static int sockAddrEqual(
|
|||
if (a->ss_family != b->ss_family)
|
||||
return 0;
|
||||
|
||||
if (a->ss_family == AF_INET) {
|
||||
if (a->ss_family == WOLFSSL_IP4) {
|
||||
|
||||
if (aLen < (XSOCKLENT)sizeof(SOCKADDR_IN))
|
||||
return 0;
|
||||
|
@ -349,7 +362,7 @@ static int sockAddrEqual(
|
|||
}
|
||||
|
||||
#ifdef WOLFSSL_IPV6
|
||||
if (a->ss_family == AF_INET6) {
|
||||
if (a->ss_family == WOLFSSL_IP6) {
|
||||
SOCKADDR_IN6 *a6, *b6;
|
||||
|
||||
if (aLen < (XSOCKLENT)sizeof(SOCKADDR_IN6))
|
||||
|
@ -367,11 +380,20 @@ static int sockAddrEqual(
|
|||
|
||||
return 1;
|
||||
}
|
||||
#endif /* WOLFSSL_HAVE_IPV6 */
|
||||
#endif /* WOLFSSL_IPV6 */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef WOLFSSL_IPV6
|
||||
static int PeerIsIpv6(const SOCKADDR_S *peer, XSOCKLENT len)
|
||||
{
|
||||
if (len < sizeof(peer->ss_family))
|
||||
return 0;
|
||||
return peer->ss_family == WOLFSSL_IP6;
|
||||
}
|
||||
#endif /* !WOLFSSL_IPV6 */
|
||||
|
||||
static int isDGramSock(int sfd)
|
||||
{
|
||||
char type = 0;
|
||||
|
@ -400,6 +422,11 @@ int EmbedReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx)
|
|||
SOCKADDR_S lclPeer;
|
||||
SOCKADDR_S* peer;
|
||||
XSOCKLENT peerSz = 0;
|
||||
#ifndef NO_ASN_TIME
|
||||
word32 start = 0;
|
||||
#elif !defined(DTLS_RECEIVEFROM_NO_TIMEOUT_ON_INVALID_PEER)
|
||||
word32 invalidPeerPackets = 0;
|
||||
#endif
|
||||
|
||||
WOLFSSL_ENTER("EmbedReceiveFrom");
|
||||
|
||||
|
@ -407,6 +434,12 @@ int EmbedReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx)
|
|||
peer = NULL;
|
||||
}
|
||||
else if (dtlsCtx->userSet) {
|
||||
#ifndef WOLFSSL_IPV6
|
||||
if (PeerIsIpv6((SOCKADDR_S*)dtlsCtx->peer.sa, dtlsCtx->peer.sz)) {
|
||||
WOLFSSL_MSG("ipv6 dtls peer set but no ipv6 support compiled");
|
||||
return NOT_COMPILED_IN;
|
||||
}
|
||||
#endif
|
||||
peer = &lclPeer;
|
||||
XMEMSET(&lclPeer, 0, sizeof(lclPeer));
|
||||
peerSz = sizeof(lclPeer);
|
||||
|
@ -438,10 +471,26 @@ int EmbedReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx)
|
|||
}
|
||||
#endif /* WOLFSSL_DTLS13 */
|
||||
|
||||
if (!doDtlsTimeout)
|
||||
dtls_timeout = 0;
|
||||
do {
|
||||
|
||||
if (!wolfSSL_get_using_nonblock(ssl)) {
|
||||
if (!doDtlsTimeout) {
|
||||
dtls_timeout = 0;
|
||||
}
|
||||
else {
|
||||
#ifndef NO_ASN_TIME
|
||||
if (start == 0) {
|
||||
start = LowResTimer();
|
||||
}
|
||||
else {
|
||||
dtls_timeout -= LowResTimer() - start;
|
||||
start = LowResTimer();
|
||||
if (dtls_timeout < 0 || dtls_timeout > DTLS_TIMEOUT_MAX)
|
||||
return WOLFSSL_CBIO_ERR_TIMEOUT;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!wolfSSL_get_using_nonblock(ssl)) {
|
||||
#ifdef USE_WINDOWS_API
|
||||
DWORD timeout = dtls_timeout * 1000;
|
||||
#ifdef WOLFSSL_DTLS13
|
||||
|
@ -464,87 +513,101 @@ int EmbedReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx)
|
|||
#endif /* WOLFSSL_DTLS13 */
|
||||
timeout.tv_sec = dtls_timeout;
|
||||
#endif
|
||||
if (setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout,
|
||||
sizeof(timeout)) != 0) {
|
||||
if (setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout,
|
||||
sizeof(timeout)) != 0) {
|
||||
WOLFSSL_MSG("setsockopt rcvtimeo failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifndef NO_ASN_TIME
|
||||
else if(IsSCR(ssl)) {
|
||||
if (ssl->dtls_start_timeout &&
|
||||
LowResTimer() - ssl->dtls_start_timeout > (word32)dtls_timeout) {
|
||||
ssl->dtls_start_timeout = 0;
|
||||
return WOLFSSL_CBIO_ERR_TIMEOUT;
|
||||
else if (IsSCR(ssl)) {
|
||||
if (ssl->dtls_start_timeout &&
|
||||
LowResTimer() - ssl->dtls_start_timeout >
|
||||
(word32)dtls_timeout) {
|
||||
ssl->dtls_start_timeout = 0;
|
||||
return WOLFSSL_CBIO_ERR_TIMEOUT;
|
||||
}
|
||||
else if (!ssl->dtls_start_timeout) {
|
||||
ssl->dtls_start_timeout = LowResTimer();
|
||||
}
|
||||
}
|
||||
else if (!ssl->dtls_start_timeout) {
|
||||
ssl->dtls_start_timeout = LowResTimer();
|
||||
}
|
||||
}
|
||||
#endif /* !NO_ASN_TIME */
|
||||
|
||||
recvd = (int)DTLS_RECVFROM_FUNCTION(sd, buf, sz, ssl->rflags,
|
||||
(SOCKADDR*)peer, peer != NULL ? &peerSz : NULL);
|
||||
recvd = (int)DTLS_RECVFROM_FUNCTION(sd, buf, sz, ssl->rflags,
|
||||
(SOCKADDR*)peer, peer != NULL ? &peerSz : NULL);
|
||||
|
||||
/* From the RECV(2) man page
|
||||
* The returned address is truncated if the buffer provided is too small; in
|
||||
* this case, addrlen will return a value greater than was supplied to the
|
||||
* call.
|
||||
*/
|
||||
if (dtlsCtx->connected) {
|
||||
/* No need to sanitize the value of peerSz */
|
||||
}
|
||||
else if (dtlsCtx->userSet) {
|
||||
/* Truncate peer size */
|
||||
if (peerSz > (XSOCKLENT)sizeof(lclPeer))
|
||||
peerSz = (XSOCKLENT)sizeof(lclPeer);
|
||||
}
|
||||
else {
|
||||
/* Truncate peer size */
|
||||
if (peerSz > (XSOCKLENT)dtlsCtx->peer.bufSz)
|
||||
peerSz = (XSOCKLENT)dtlsCtx->peer.bufSz;
|
||||
}
|
||||
|
||||
recvd = TranslateReturnCode(recvd, sd);
|
||||
|
||||
if (recvd < 0) {
|
||||
WOLFSSL_MSG("Embed Receive From error");
|
||||
recvd = TranslateIoError(recvd);
|
||||
if (recvd == WOLFSSL_CBIO_ERR_WANT_READ &&
|
||||
!wolfSSL_dtls_get_using_nonblock(ssl)) {
|
||||
recvd = WOLFSSL_CBIO_ERR_TIMEOUT;
|
||||
/* From the RECV(2) man page
|
||||
* The returned address is truncated if the buffer provided is too
|
||||
* small; in this case, addrlen will return a value greater than was
|
||||
* supplied to the call.
|
||||
*/
|
||||
if (dtlsCtx->connected) {
|
||||
/* No need to sanitize the value of peerSz */
|
||||
}
|
||||
return recvd;
|
||||
}
|
||||
else if (recvd == 0) {
|
||||
if (!isDGramSock(sd)) {
|
||||
/* Closed TCP connection */
|
||||
recvd = WOLFSSL_CBIO_ERR_CONN_CLOSE;
|
||||
else if (dtlsCtx->userSet) {
|
||||
/* Truncate peer size */
|
||||
if (peerSz > (XSOCKLENT)sizeof(lclPeer))
|
||||
peerSz = (XSOCKLENT)sizeof(lclPeer);
|
||||
}
|
||||
else {
|
||||
WOLFSSL_MSG("Ignoring 0-length datagram");
|
||||
/* Truncate peer size */
|
||||
if (peerSz > (XSOCKLENT)dtlsCtx->peer.bufSz)
|
||||
peerSz = (XSOCKLENT)dtlsCtx->peer.bufSz;
|
||||
}
|
||||
return recvd;
|
||||
}
|
||||
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,
|
||||
dtlsCtx->peer.sz))) {
|
||||
WOLFSSL_MSG(" Ignored packet from invalid peer");
|
||||
return WOLFSSL_CBIO_ERR_WANT_READ;
|
||||
|
||||
recvd = TranslateReturnCode(recvd, sd);
|
||||
|
||||
if (recvd < 0) {
|
||||
WOLFSSL_MSG("Embed Receive From error");
|
||||
recvd = TranslateIoError(recvd);
|
||||
if (recvd == WOLFSSL_CBIO_ERR_WANT_READ &&
|
||||
!wolfSSL_dtls_get_using_nonblock(ssl)) {
|
||||
recvd = WOLFSSL_CBIO_ERR_TIMEOUT;
|
||||
}
|
||||
return recvd;
|
||||
}
|
||||
else if (recvd == 0) {
|
||||
if (!isDGramSock(sd)) {
|
||||
/* Closed TCP connection */
|
||||
recvd = WOLFSSL_CBIO_ERR_CONN_CLOSE;
|
||||
}
|
||||
else {
|
||||
WOLFSSL_MSG("Ignoring 0-length datagram");
|
||||
continue;
|
||||
}
|
||||
return recvd;
|
||||
}
|
||||
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,
|
||||
dtlsCtx->peer.sz))) {
|
||||
WOLFSSL_MSG(" Ignored packet from invalid peer");
|
||||
#if defined(NO_ASN_TIME) && \
|
||||
!defined(DTLS_RECEIVEFROM_NO_TIMEOUT_ON_INVALID_PEER)
|
||||
if (doDtlsTimeout) {
|
||||
invalidPeerPackets++;
|
||||
if (invalidPeerPackets > DTLS_RECEIVEFROM_MAX_INVALID_PEER)
|
||||
return wolfSSL_dtls_get_using_nonblock(ssl)
|
||||
? WOLFSSL_CBIO_ERR_WANT_READ
|
||||
: WOLFSSL_CBIO_ERR_TIMEOUT;
|
||||
}
|
||||
#endif /* NO_ASN_TIME && !DTLS_RECEIVEFROM_NO_TIMEOUT_ON_INVALID_PEER */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Store size of saved address */
|
||||
dtlsCtx->peer.sz = peerSz;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Store size of saved address */
|
||||
dtlsCtx->peer.sz = peerSz;
|
||||
}
|
||||
#ifndef NO_ASN_TIME
|
||||
ssl->dtls_start_timeout = 0;
|
||||
ssl->dtls_start_timeout = 0;
|
||||
#endif /* !NO_ASN_TIME */
|
||||
break;
|
||||
} while (1);
|
||||
|
||||
return recvd;
|
||||
}
|
||||
|
@ -569,6 +632,12 @@ int EmbedSendTo(WOLFSSL* ssl, char *buf, int sz, void *ctx)
|
|||
else if (!dtlsCtx->connected) {
|
||||
peer = (const SOCKADDR_S*)dtlsCtx->peer.sa;
|
||||
peerSz = dtlsCtx->peer.sz;
|
||||
#ifndef WOLFSSL_IPV6
|
||||
if (PeerIsIpv6(peer, peerSz)) {
|
||||
WOLFSSL_MSG("ipv6 dtls peer setted but no ipv6 support compiled");
|
||||
return NOT_COMPILED_IN;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
sent = (int)DTLS_SENDTO_FUNCTION(sd, buf, sz, ssl->wflags,
|
||||
|
|
196
tests/api.c
196
tests/api.c
|
@ -5435,6 +5435,9 @@ static THREAD_RETURN WOLFSSL_THREAD test_server_nofail(void* args)
|
|||
input[idx] = '\0';
|
||||
fprintf(stderr, "Client message: %s\n", input);
|
||||
}
|
||||
else if (idx < 0) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (wolfSSL_write(ssl, msg, sizeof(msg)) != sizeof(msg)) {
|
||||
/*err_sys("SSL_write failed");*/
|
||||
|
@ -5684,8 +5687,6 @@ done:
|
|||
}
|
||||
#endif /* defined(OPENSSL_EXTRA) && !defined(NO_SESSION_CACHE) && !defined(WOLFSSL_TLS13) */
|
||||
|
||||
typedef int (*cbType)(WOLFSSL_CTX *ctx, WOLFSSL *ssl);
|
||||
|
||||
static int test_client_nofail(void* args, cbType cb)
|
||||
{
|
||||
#if !defined(NO_WOLFSSL_CLIENT)
|
||||
|
@ -5928,8 +5929,8 @@ done:
|
|||
return 0;
|
||||
}
|
||||
|
||||
void test_wolfSSL_client_server_nofail(callback_functions* client_cb,
|
||||
callback_functions* server_cb)
|
||||
void test_wolfSSL_client_server_nofail_ex(callback_functions* client_cb,
|
||||
callback_functions* server_cb, cbType client_on_handshake)
|
||||
{
|
||||
func_args client_args;
|
||||
func_args server_args;
|
||||
|
@ -5958,7 +5959,7 @@ void test_wolfSSL_client_server_nofail(callback_functions* client_cb,
|
|||
|
||||
start_thread(test_server_nofail, &server_args, &serverThread);
|
||||
wait_tcp_ready(&server_args);
|
||||
test_client_nofail(&client_args, NULL);
|
||||
test_client_nofail(&client_args, client_on_handshake);
|
||||
join_thread(serverThread);
|
||||
|
||||
client_cb->return_code = client_args.return_code;
|
||||
|
@ -5971,6 +5972,13 @@ void test_wolfSSL_client_server_nofail(callback_functions* client_cb,
|
|||
#endif
|
||||
}
|
||||
|
||||
void test_wolfSSL_client_server_nofail(callback_functions* client_cb,
|
||||
callback_functions* server_cb)
|
||||
{
|
||||
test_wolfSSL_client_server_nofail_ex(client_cb, server_cb, NULL);
|
||||
}
|
||||
|
||||
|
||||
#if defined(OPENSSL_EXTRA) && !defined(NO_SESSION_CACHE) && \
|
||||
!defined(WOLFSSL_TLS13) && !defined(NO_WOLFSSL_CLIENT)
|
||||
static void test_client_reuse_WOLFSSLobj(void* args, void *cb, void* server_args)
|
||||
|
@ -65917,6 +65925,182 @@ static int test_wolfSSL_dtls13_null_cipher(void)
|
|||
return TEST_SKIPPED;
|
||||
}
|
||||
#endif
|
||||
#if defined(WOLFSSL_DTLS) && !defined(WOLFSSL_NO_TLS12) && \
|
||||
!defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER) && \
|
||||
!defined(SINGLE_THREADED)
|
||||
|
||||
static int test_dtls_msg_get_connected_port(int fd, word16 *port)
|
||||
{
|
||||
SOCKADDR_S peer;
|
||||
XSOCKLENT len;
|
||||
int ret;
|
||||
|
||||
XMEMSET((byte*)&peer, 0, sizeof(peer));
|
||||
len = sizeof(peer);
|
||||
ret = getpeername(fd, (SOCKADDR*)&peer, &len);
|
||||
if (ret != 0 || len > sizeof(peer))
|
||||
return -1;
|
||||
switch (peer.ss_family) {
|
||||
#ifdef WOLFSSL_IPV6
|
||||
case WOLFSSL_IP6: {
|
||||
*port = ntohs(((SOCKADDR_IN6*)&peer)->sin6_port);
|
||||
break;
|
||||
}
|
||||
#endif /* WOLFSSL_IPV6 */
|
||||
case WOLFSSL_IP4:
|
||||
*port = ntohs(((SOCKADDR_IN*)&peer)->sin_port);
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int test_dtls_msg_from_other_peer_cb(WOLFSSL_CTX *ctx, WOLFSSL *ssl)
|
||||
{
|
||||
char buf[1] = {'t'};
|
||||
SOCKADDR_IN_T addr;
|
||||
int sock_fd;
|
||||
word16 port;
|
||||
int err;
|
||||
|
||||
(void)ssl;
|
||||
(void)ctx;
|
||||
|
||||
err = test_dtls_msg_get_connected_port(wolfSSL_get_fd(ssl), &port);
|
||||
if (err != 0)
|
||||
return -1;
|
||||
|
||||
sock_fd = socket(AF_INET_V, SOCK_DGRAM, 0);
|
||||
if (sock_fd == -1)
|
||||
return -1;
|
||||
build_addr(&addr, wolfSSLIP, port, 1, 0);
|
||||
|
||||
/* send a packet to the server. Being another socket, the kernel will ensure
|
||||
* the source port will be different. */
|
||||
err = (int)sendto(sock_fd, buf, sizeof(buf), 0, (SOCKADDR*)&addr,
|
||||
sizeof(addr));
|
||||
|
||||
close(sock_fd);
|
||||
if (err == -1)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* setup a SSL session but just after the handshake send a packet to the server
|
||||
* with a source address different than the one of the connected client. The I/O
|
||||
* callback EmbedRecvFrom should just ignore the packet. Sending of the packet
|
||||
* is done in test_dtls_msg_from_other_peer_cb */
|
||||
static int test_dtls_msg_from_other_peer(void)
|
||||
{
|
||||
callback_functions client_cbs;
|
||||
callback_functions server_cbs;
|
||||
|
||||
XMEMSET((byte*)&client_cbs, 0, sizeof(client_cbs));
|
||||
XMEMSET((byte*)&server_cbs, 0, sizeof(server_cbs));
|
||||
|
||||
client_cbs.method = wolfDTLSv1_2_client_method;
|
||||
server_cbs.method = wolfDTLSv1_2_server_method;
|
||||
client_cbs.doUdp = 1;
|
||||
server_cbs.doUdp = 1;
|
||||
|
||||
test_wolfSSL_client_server_nofail_ex(&client_cbs, &server_cbs,
|
||||
test_dtls_msg_from_other_peer_cb);
|
||||
|
||||
if (client_cbs.return_code != WOLFSSL_SUCCESS ||
|
||||
server_cbs.return_code != WOLFSSL_SUCCESS)
|
||||
return TEST_FAIL;
|
||||
|
||||
return TEST_SUCCESS;
|
||||
}
|
||||
#else
|
||||
static int test_dtls_msg_from_other_peer(void)
|
||||
{
|
||||
return TEST_SKIPPED;
|
||||
}
|
||||
#endif /* defined(WOLFSSL_DTLS) && !defined(WOLFSSL_NO_TLS12) && \
|
||||
* !defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER) && \
|
||||
* !defined(SINGLE_THREADED) */
|
||||
#if defined(WOLFSSL_DTLS) && !defined(WOLFSSL_IPV6) && \
|
||||
!defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER) && \
|
||||
defined(HAVE_IO_TESTS_DEPENDENCIES)
|
||||
static int test_dtls_ipv6_check(void)
|
||||
{
|
||||
WOLFSSL_CTX *ctx_c = NULL, *ctx_s = NULL;
|
||||
WOLFSSL *ssl_c = NULL, *ssl_s = NULL;
|
||||
SOCKADDR_IN fake_addr6;
|
||||
int sockfd;
|
||||
int ret;
|
||||
|
||||
ctx_c = wolfSSL_CTX_new(wolfDTLSv1_2_client_method());
|
||||
if (ctx_c == NULL)
|
||||
return TEST_FAIL;
|
||||
ssl_c = wolfSSL_new(ctx_c);
|
||||
if (ssl_c == NULL)
|
||||
return TEST_FAIL;
|
||||
ctx_s = wolfSSL_CTX_new(wolfDTLSv1_2_server_method());
|
||||
if (ctx_s == NULL)
|
||||
return TEST_FAIL;
|
||||
ret = wolfSSL_CTX_use_PrivateKey_file(ctx_s, svrKeyFile,
|
||||
WOLFSSL_FILETYPE_PEM);
|
||||
if (ret != WOLFSSL_SUCCESS)
|
||||
return- -1;
|
||||
ret = wolfSSL_CTX_use_certificate_file(ctx_s, svrCertFile,
|
||||
WOLFSSL_FILETYPE_PEM);
|
||||
if (ret != WOLFSSL_SUCCESS)
|
||||
return -1;
|
||||
ssl_s = wolfSSL_new(ctx_s);
|
||||
if (ssl_s == NULL)
|
||||
return TEST_FAIL;
|
||||
XMEMSET((byte*)&fake_addr6, 0, sizeof(fake_addr6));
|
||||
/* mimic a sockaddr_in6 struct, this way we can't test without
|
||||
* WOLFSSL_IPV6 */
|
||||
fake_addr6.sin_family = WOLFSSL_IP6;
|
||||
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (sockfd == -1)
|
||||
return TEST_FAIL;
|
||||
ret = wolfSSL_set_fd(ssl_c, sockfd);
|
||||
if (ret != WOLFSSL_SUCCESS)
|
||||
return TEST_FAIL;
|
||||
/* can't return error here, as the peer is opaque for wolfssl library at
|
||||
* this point */
|
||||
ret = wolfSSL_dtls_set_peer(ssl_c, &fake_addr6, sizeof(fake_addr6));
|
||||
if (ret != WOLFSSL_SUCCESS)
|
||||
return TEST_FAIL;
|
||||
ret = fcntl(sockfd, F_SETFL, O_NONBLOCK);
|
||||
if (ret == -1)
|
||||
return TEST_FAIL;
|
||||
wolfSSL_dtls_set_using_nonblock(ssl_c, 1);
|
||||
ret = wolfSSL_connect(ssl_c);
|
||||
if (ret != WOLFSSL_FAILURE && ssl_c->error != SOCKET_ERROR_E)
|
||||
return TEST_FAIL;
|
||||
|
||||
ret = wolfSSL_dtls_set_peer(ssl_s, &fake_addr6, sizeof(fake_addr6));
|
||||
if (ret != WOLFSSL_SUCCESS)
|
||||
return TEST_FAIL;
|
||||
/* re-use the socket */
|
||||
ret = wolfSSL_set_fd(ssl_c, sockfd);
|
||||
if (ret != WOLFSSL_SUCCESS)
|
||||
return TEST_FAIL;
|
||||
wolfSSL_dtls_set_using_nonblock(ssl_s, 1);
|
||||
ret = wolfSSL_accept(ssl_s);
|
||||
if (ret != WOLFSSL_FAILURE && ssl_s->error != SOCKET_ERROR_E)
|
||||
return TEST_FAIL;
|
||||
close(sockfd);
|
||||
|
||||
wolfSSL_free(ssl_c);
|
||||
wolfSSL_CTX_free(ctx_c);
|
||||
wolfSSL_free(ssl_s);
|
||||
wolfSSL_CTX_free(ctx_s);
|
||||
return TEST_SUCCESS;
|
||||
}
|
||||
#else
|
||||
static int test_dtls_ipv6_check(void)
|
||||
{
|
||||
return TEST_SKIPPED;
|
||||
}
|
||||
#endif
|
||||
/*----------------------------------------------------------------------------*
|
||||
| Main
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
@ -66955,6 +67139,8 @@ TEST_CASE testCases[] = {
|
|||
TEST_DECL(test_override_alt_cert_chain),
|
||||
TEST_DECL(test_dtls13_bad_epoch_ch),
|
||||
TEST_DECL(test_wolfSSL_dtls13_null_cipher),
|
||||
TEST_DECL(test_dtls_msg_from_other_peer),
|
||||
TEST_DECL(test_dtls_ipv6_check),
|
||||
/* If at some point a stub get implemented this test should fail indicating
|
||||
* a need to implement a new test case
|
||||
*/
|
||||
|
|
|
@ -636,6 +636,10 @@ typedef THREAD_RETURN WOLFSSL_THREAD THREAD_FUNC(void*);
|
|||
void start_thread(THREAD_FUNC fun, func_args* args, THREAD_TYPE* thread);
|
||||
void join_thread(THREAD_TYPE thread);
|
||||
|
||||
typedef int (*cbType)(WOLFSSL_CTX *ctx, WOLFSSL *ssl);
|
||||
|
||||
void test_wolfSSL_client_server_nofail_ex(callback_functions* client_cb,
|
||||
callback_functions* server_cb, cbType client_on_handshake);
|
||||
void test_wolfSSL_client_server_nofail(callback_functions* client_cb,
|
||||
callback_functions* server_cb);
|
||||
|
||||
|
|
Loading…
Reference in New Issue