From e02da0819292e4cc96be7dad9b859f3b03dd91b7 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Mon, 10 Feb 2025 13:49:03 +0100 Subject: [PATCH 01/10] Reorganize utility functions into tests/utils.c and testsuite/utils.c --- tests/api.c | 250 +------------------------------------- tests/include.am | 2 + tests/utils.c | 273 ++++++++++++++++++++++++++++++++++++++++++ tests/utils.h | 176 ++------------------------- testsuite/include.am | 1 + testsuite/testsuite.c | 4 +- testsuite/utils.c | 191 +++++++++++++++++++++++++++++ testsuite/utils.h | 40 +++++++ wolfssl/test.h | 10 -- 9 files changed, 528 insertions(+), 419 deletions(-) create mode 100644 tests/utils.c create mode 100644 testsuite/utils.c create mode 100644 testsuite/utils.h diff --git a/tests/api.c b/tests/api.c index e7a553bbe..4733d790c 100644 --- a/tests/api.c +++ b/tests/api.c @@ -56,6 +56,7 @@ #include #include +#include /* for testing compatibility layer callbacks */ #include "examples/server/server.h" @@ -581,250 +582,6 @@ int testDevId = WOLFSSL_CAAM_DEVID; int testDevId = INVALID_DEVID; #endif -#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && !defined(NO_RSA) && \ - !defined(NO_WOLFSSL_SERVER) && !defined(NO_WOLFSSL_CLIENT) && \ - (!defined(WOLFSSL_NO_TLS12) || defined(WOLFSSL_TLS13)) - -/* This set of memio functions allows for more fine tuned control of the TLS - * connection operations. For new tests, try to use ssl_memio first. */ - -/* To dump the memory in gdb use - * dump memory client.bin test_ctx.c_buff test_ctx.c_buff+test_ctx.c_len - * dump memory server.bin test_ctx.s_buff test_ctx.s_buff+test_ctx.s_len - * This can be imported into Wireshark by transforming the file with - * od -Ax -tx1 -v client.bin > client.bin.hex - * od -Ax -tx1 -v server.bin > server.bin.hex - * And then loading test_output.dump.hex into Wireshark using the - * "Import from Hex Dump..." option ion and selecting the TCP - * encapsulation option. - */ - -#define HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES - -static WC_INLINE int test_memio_write_cb(WOLFSSL *ssl, char *data, int sz, - void *ctx) -{ - struct test_memio_ctx *test_ctx; - byte *buf; - int *len; - - test_ctx = (struct test_memio_ctx*)ctx; - - if (wolfSSL_GetSide(ssl) == WOLFSSL_SERVER_END) { - buf = test_ctx->c_buff; - len = &test_ctx->c_len; - } - else { - buf = test_ctx->s_buff; - len = &test_ctx->s_len; - } - - if ((unsigned)(*len + sz) > TEST_MEMIO_BUF_SZ) - return WOLFSSL_CBIO_ERR_WANT_WRITE; - -#ifdef WOLFSSL_DUMP_MEMIO_STREAM - { - char dump_file_name[64]; - WOLFSSL_BIO *dump_file; - sprintf(dump_file_name, "%s/%s.dump", tmpDirName, currentTestName); - dump_file = wolfSSL_BIO_new_file(dump_file_name, "a"); - if (dump_file != NULL) { - (void)wolfSSL_BIO_write(dump_file, data, sz); - wolfSSL_BIO_free(dump_file); - } - } -#endif - XMEMCPY(buf + *len, data, (size_t)sz); - *len += sz; - - return sz; -} - -static WC_INLINE int test_memio_read_cb(WOLFSSL *ssl, char *data, int sz, - void *ctx) -{ - struct test_memio_ctx *test_ctx; - int read_sz; - byte *buf; - int *len; - - test_ctx = (struct test_memio_ctx*)ctx; - - if (wolfSSL_GetSide(ssl) == WOLFSSL_SERVER_END) { - buf = test_ctx->s_buff; - len = &test_ctx->s_len; - } - else { - buf = test_ctx->c_buff; - len = &test_ctx->c_len; - } - - if (*len == 0) - return WOLFSSL_CBIO_ERR_WANT_READ; - - read_sz = sz < *len ? sz : *len; - - XMEMCPY(data, buf, (size_t)read_sz); - XMEMMOVE(buf, buf + read_sz,(size_t) (*len - read_sz)); - - *len -= read_sz; - - return read_sz; -} - -int test_memio_do_handshake(WOLFSSL *ssl_c, WOLFSSL *ssl_s, - int max_rounds, int *rounds) -{ - byte handshake_complete = 0, hs_c = 0, hs_s = 0; - int ret, err; - - if (rounds != NULL) - *rounds = 0; - while (!handshake_complete && max_rounds > 0) { - if (!hs_c) { - wolfSSL_SetLoggingPrefix("client"); - ret = wolfSSL_connect(ssl_c); - wolfSSL_SetLoggingPrefix(NULL); - if (ret == WOLFSSL_SUCCESS) { - hs_c = 1; - } - else { - err = wolfSSL_get_error(ssl_c, ret); - if (err != WOLFSSL_ERROR_WANT_READ && - err != WOLFSSL_ERROR_WANT_WRITE) - return -1; - } - } - if (!hs_s) { - wolfSSL_SetLoggingPrefix("server"); - ret = wolfSSL_accept(ssl_s); - wolfSSL_SetLoggingPrefix(NULL); - if (ret == WOLFSSL_SUCCESS) { - hs_s = 1; - } - else { - err = wolfSSL_get_error(ssl_s, ret); - if (err != WOLFSSL_ERROR_WANT_READ && - err != WOLFSSL_ERROR_WANT_WRITE) - return -1; - } - } - handshake_complete = hs_c && hs_s; - max_rounds--; - if (rounds != NULL) - *rounds = *rounds + 1; - } - - if (!handshake_complete) - return -1; - - return 0; -} - -int test_memio_setup_ex(struct test_memio_ctx *ctx, - WOLFSSL_CTX **ctx_c, WOLFSSL_CTX **ctx_s, WOLFSSL **ssl_c, WOLFSSL **ssl_s, - method_provider method_c, method_provider method_s, - byte *caCert, int caCertSz, byte *serverCert, int serverCertSz, - byte *serverKey, int serverKeySz) -{ - int ret; - (void)caCert; - (void)caCertSz; - (void)serverCert; - (void)serverCertSz; - (void)serverKey; - (void)serverKeySz; - - if (ctx_c != NULL && *ctx_c == NULL) { - *ctx_c = wolfSSL_CTX_new(method_c()); - if (*ctx_c == NULL) - return -1; -#ifndef NO_CERTS - if (caCert == NULL) { - ret = wolfSSL_CTX_load_verify_locations(*ctx_c, caCertFile, 0); - } - else { - ret = wolfSSL_CTX_load_verify_buffer(*ctx_c, caCert, (long)caCertSz, - WOLFSSL_FILETYPE_ASN1); - } - if (ret != WOLFSSL_SUCCESS) - return -1; -#endif /* NO_CERTS */ - wolfSSL_SetIORecv(*ctx_c, test_memio_read_cb); - wolfSSL_SetIOSend(*ctx_c, test_memio_write_cb); - if (ctx->c_ciphers != NULL) { - ret = wolfSSL_CTX_set_cipher_list(*ctx_c, ctx->c_ciphers); - if (ret != WOLFSSL_SUCCESS) - return -1; - } - } - - if (ctx_s != NULL && *ctx_s == NULL) { - *ctx_s = wolfSSL_CTX_new(method_s()); - if (*ctx_s == NULL) - return -1; -#ifndef NO_CERTS - if (serverKey == NULL) { - ret = wolfSSL_CTX_use_PrivateKey_file(*ctx_s, svrKeyFile, - WOLFSSL_FILETYPE_PEM); - } - else { - ret = wolfSSL_CTX_use_PrivateKey_buffer(*ctx_s, serverKey, - (long)serverKeySz, WOLFSSL_FILETYPE_ASN1); - } - if (ret != WOLFSSL_SUCCESS) - return- -1; - - if (serverCert == NULL) { - ret = wolfSSL_CTX_use_certificate_file(*ctx_s, svrCertFile, - WOLFSSL_FILETYPE_PEM); - } - else { - ret = wolfSSL_CTX_use_certificate_chain_buffer_format(*ctx_s, - serverCert, (long)serverCertSz, WOLFSSL_FILETYPE_ASN1); - } - if (ret != WOLFSSL_SUCCESS) - return -1; -#endif /* NO_CERTS */ - wolfSSL_SetIORecv(*ctx_s, test_memio_read_cb); - wolfSSL_SetIOSend(*ctx_s, test_memio_write_cb); - if (ctx->s_ciphers != NULL) { - ret = wolfSSL_CTX_set_cipher_list(*ctx_s, ctx->s_ciphers); - if (ret != WOLFSSL_SUCCESS) - return -1; - } - } - - if (ctx_c != NULL && ssl_c != NULL) { - *ssl_c = wolfSSL_new(*ctx_c); - if (*ssl_c == NULL) - return -1; - wolfSSL_SetIOWriteCtx(*ssl_c, ctx); - wolfSSL_SetIOReadCtx(*ssl_c, ctx); - } - if (ctx_s != NULL && ssl_s != NULL) { - *ssl_s = wolfSSL_new(*ctx_s); - if (*ssl_s == NULL) - return -1; - wolfSSL_SetIOWriteCtx(*ssl_s, ctx); - wolfSSL_SetIOReadCtx(*ssl_s, ctx); -#if !defined(NO_DH) - SetDH(*ssl_s); -#endif - } - - return 0; -} - -int test_memio_setup(struct test_memio_ctx *ctx, - WOLFSSL_CTX **ctx_c, WOLFSSL_CTX **ctx_s, WOLFSSL **ssl_c, WOLFSSL **ssl_s, - method_provider method_c, method_provider method_s) -{ - return test_memio_setup_ex(ctx, ctx_c, ctx_s, ssl_c, ssl_s, method_c, - method_s, NULL, 0, NULL, 0, NULL, 0); -} -#endif - /*----------------------------------------------------------------------------* | BIO with fixed read/write size *----------------------------------------------------------------------------*/ @@ -98204,6 +97961,11 @@ static int test_get_signature_nid(void) TGSN_TLS13_ED448("ED448", NID_ED448, NID_sha512), #endif }; + /* These correspond to WOLFSSL_SSLV3...WOLFSSL_DTLSV1_3 */ + const char* tls_desc[] = { + "SSLv3", "TLSv1.0", "TLSv1.1", "TLSv1.2", "TLSv1.3", + "DTLSv1.0", "DTLSv1.2", "DTLSv1.3" + }; printf("\n"); diff --git a/tests/include.am b/tests/include.am index 65ba734ad..0f4df2de1 100644 --- a/tests/include.am +++ b/tests/include.am @@ -8,6 +8,8 @@ noinst_PROGRAMS += tests/unit.test tests_unit_test_SOURCES = \ tests/unit.c \ tests/api.c \ + tests/utils.c \ + testsuite/utils.c \ tests/suites.c \ tests/hash.c \ tests/w64wrapper.c \ diff --git a/tests/utils.c b/tests/utils.c new file mode 100644 index 000000000..bbdd5cf53 --- /dev/null +++ b/tests/utils.c @@ -0,0 +1,273 @@ +/* utils.c + * + * Copyright (C) 2006-2025 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 + */ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#if !defined(WOLFSSL_USER_SETTINGS) && !defined(WOLFSSL_NO_OPTIONS_H) + #include +#endif +#include + +#include +#include +#include + +#ifdef HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES + +/* This set of memio functions allows for more fine tuned control of the TLS + * connection operations. For new tests, try to use ssl_memio first. */ + +/* To dump the memory in gdb use + * dump memory client.bin test_ctx.c_buff test_ctx.c_buff+test_ctx.c_len + * dump memory server.bin test_ctx.s_buff test_ctx.s_buff+test_ctx.s_len + * This can be imported into Wireshark by transforming the file with + * od -Ax -tx1 -v client.bin > client.bin.hex + * od -Ax -tx1 -v server.bin > server.bin.hex + * And then loading test_output.dump.hex into Wireshark using the + * "Import from Hex Dump..." option ion and selecting the TCP + * encapsulation option. + */ + +int test_memio_write_cb(WOLFSSL *ssl, char *data, int sz, void *ctx) +{ + struct test_memio_ctx *test_ctx; + byte *buf; + int *len; + + test_ctx = (struct test_memio_ctx*)ctx; + + if (wolfSSL_GetSide(ssl) == WOLFSSL_SERVER_END) { + buf = test_ctx->c_buff; + len = &test_ctx->c_len; + } + else { + buf = test_ctx->s_buff; + len = &test_ctx->s_len; + } + + if ((unsigned)(*len + sz) > TEST_MEMIO_BUF_SZ) + return WOLFSSL_CBIO_ERR_WANT_WRITE; + +#ifdef WOLFSSL_DUMP_MEMIO_STREAM + { + char dump_file_name[64]; + WOLFSSL_BIO *dump_file; + sprintf(dump_file_name, "%s/%s.dump", tmpDirName, currentTestName); + dump_file = wolfSSL_BIO_new_file(dump_file_name, "a"); + if (dump_file != NULL) { + (void)wolfSSL_BIO_write(dump_file, data, sz); + wolfSSL_BIO_free(dump_file); + } + } +#endif + XMEMCPY(buf + *len, data, (size_t)sz); + *len += sz; + + return sz; +} + +int test_memio_read_cb(WOLFSSL *ssl, char *data, int sz, void *ctx) +{ + struct test_memio_ctx *test_ctx; + int read_sz; + byte *buf; + int *len; + + test_ctx = (struct test_memio_ctx*)ctx; + + if (wolfSSL_GetSide(ssl) == WOLFSSL_SERVER_END) { + buf = test_ctx->s_buff; + len = &test_ctx->s_len; + } + else { + buf = test_ctx->c_buff; + len = &test_ctx->c_len; + } + + if (*len == 0) + return WOLFSSL_CBIO_ERR_WANT_READ; + + read_sz = sz < *len ? sz : *len; + + XMEMCPY(data, buf, (size_t)read_sz); + XMEMMOVE(buf, buf + read_sz,(size_t) (*len - read_sz)); + + *len -= read_sz; + + return read_sz; +} + +int test_memio_do_handshake(WOLFSSL *ssl_c, WOLFSSL *ssl_s, + int max_rounds, int *rounds) +{ + byte handshake_complete = 0, hs_c = 0, hs_s = 0; + int ret, err; + + if (rounds != NULL) + *rounds = 0; + while (!handshake_complete && max_rounds > 0) { + if (!hs_c) { + wolfSSL_SetLoggingPrefix("client"); + ret = wolfSSL_connect(ssl_c); + wolfSSL_SetLoggingPrefix(NULL); + if (ret == WOLFSSL_SUCCESS) { + hs_c = 1; + } + else { + err = wolfSSL_get_error(ssl_c, ret); + if (err != WOLFSSL_ERROR_WANT_READ && + err != WOLFSSL_ERROR_WANT_WRITE) + return -1; + } + } + if (!hs_s) { + wolfSSL_SetLoggingPrefix("server"); + ret = wolfSSL_accept(ssl_s); + wolfSSL_SetLoggingPrefix(NULL); + if (ret == WOLFSSL_SUCCESS) { + hs_s = 1; + } + else { + err = wolfSSL_get_error(ssl_s, ret); + if (err != WOLFSSL_ERROR_WANT_READ && + err != WOLFSSL_ERROR_WANT_WRITE) + return -1; + } + } + handshake_complete = hs_c && hs_s; + max_rounds--; + if (rounds != NULL) + *rounds = *rounds + 1; + } + + if (!handshake_complete) + return -1; + + return 0; +} + +int test_memio_setup_ex(struct test_memio_ctx *ctx, + WOLFSSL_CTX **ctx_c, WOLFSSL_CTX **ctx_s, WOLFSSL **ssl_c, WOLFSSL **ssl_s, + method_provider method_c, method_provider method_s, + byte *caCert, int caCertSz, byte *serverCert, int serverCertSz, + byte *serverKey, int serverKeySz) +{ + int ret; + (void)caCert; + (void)caCertSz; + (void)serverCert; + (void)serverCertSz; + (void)serverKey; + (void)serverKeySz; + + if (ctx_c != NULL && *ctx_c == NULL) { + *ctx_c = wolfSSL_CTX_new(method_c()); + if (*ctx_c == NULL) + return -1; +#ifndef NO_CERTS + if (caCert == NULL) { + ret = wolfSSL_CTX_load_verify_locations(*ctx_c, caCertFile, 0); + } + else { + ret = wolfSSL_CTX_load_verify_buffer(*ctx_c, caCert, (long)caCertSz, + WOLFSSL_FILETYPE_ASN1); + } + if (ret != WOLFSSL_SUCCESS) + return -1; +#endif /* NO_CERTS */ + wolfSSL_SetIORecv(*ctx_c, test_memio_read_cb); + wolfSSL_SetIOSend(*ctx_c, test_memio_write_cb); + if (ctx->c_ciphers != NULL) { + ret = wolfSSL_CTX_set_cipher_list(*ctx_c, ctx->c_ciphers); + if (ret != WOLFSSL_SUCCESS) + return -1; + } + } + + if (ctx_s != NULL && *ctx_s == NULL) { + *ctx_s = wolfSSL_CTX_new(method_s()); + if (*ctx_s == NULL) + return -1; +#ifndef NO_CERTS + if (serverKey == NULL) { + ret = wolfSSL_CTX_use_PrivateKey_file(*ctx_s, svrKeyFile, + WOLFSSL_FILETYPE_PEM); + } + else { + ret = wolfSSL_CTX_use_PrivateKey_buffer(*ctx_s, serverKey, + (long)serverKeySz, WOLFSSL_FILETYPE_ASN1); + } + if (ret != WOLFSSL_SUCCESS) + return- -1; + + if (serverCert == NULL) { + ret = wolfSSL_CTX_use_certificate_file(*ctx_s, svrCertFile, + WOLFSSL_FILETYPE_PEM); + } + else { + ret = wolfSSL_CTX_use_certificate_chain_buffer_format(*ctx_s, + serverCert, (long)serverCertSz, WOLFSSL_FILETYPE_ASN1); + } + if (ret != WOLFSSL_SUCCESS) + return -1; +#endif /* NO_CERTS */ + wolfSSL_SetIORecv(*ctx_s, test_memio_read_cb); + wolfSSL_SetIOSend(*ctx_s, test_memio_write_cb); + if (ctx->s_ciphers != NULL) { + ret = wolfSSL_CTX_set_cipher_list(*ctx_s, ctx->s_ciphers); + if (ret != WOLFSSL_SUCCESS) + return -1; + } + } + + if (ctx_c != NULL && ssl_c != NULL) { + *ssl_c = wolfSSL_new(*ctx_c); + if (*ssl_c == NULL) + return -1; + wolfSSL_SetIOWriteCtx(*ssl_c, ctx); + wolfSSL_SetIOReadCtx(*ssl_c, ctx); + } + if (ctx_s != NULL && ssl_s != NULL) { + *ssl_s = wolfSSL_new(*ctx_s); + if (*ssl_s == NULL) + return -1; + wolfSSL_SetIOWriteCtx(*ssl_s, ctx); + wolfSSL_SetIOReadCtx(*ssl_s, ctx); +#if !defined(NO_DH) + SetDH(*ssl_s); +#endif + } + + return 0; +} + +int test_memio_setup(struct test_memio_ctx *ctx, + WOLFSSL_CTX **ctx_c, WOLFSSL_CTX **ctx_s, WOLFSSL **ssl_c, WOLFSSL **ssl_s, + method_provider method_c, method_provider method_s) +{ + return test_memio_setup_ex(ctx, ctx_c, ctx_s, ssl_c, ssl_s, method_c, + method_s, NULL, 0, NULL, 0, NULL, 0); +} + +#endif /* HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES */ + diff --git a/tests/utils.h b/tests/utils.h index 38a93cf8d..75bae2cb0 100644 --- a/tests/utils.h +++ b/tests/utils.h @@ -18,121 +18,19 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ -#ifdef HAVE_CONFIG_H - #include -#endif #include -#include +#include +#include +#include -#ifndef NO_FILESYSTEM - -#if defined(_MSC_VER) -#include -#elif defined(__WATCOMC__) -#ifdef __LINUX__ -#include -#else -#include -#endif -#endif - -#define TMP_DIR_PREFIX "tmpDir-" -/* len is length of tmpDir name, assuming - * len does not include null terminating character */ -char* create_tmp_dir(char *tmpDir, int len) -{ - if (len < (int)XSTR_SIZEOF(TMP_DIR_PREFIX)) - return NULL; - - XMEMCPY(tmpDir, TMP_DIR_PREFIX, XSTR_SIZEOF(TMP_DIR_PREFIX)); - - if (mymktemp(tmpDir, len, len - (int)XSTR_SIZEOF(TMP_DIR_PREFIX)) == NULL) - return NULL; - -#ifdef _MSC_VER - if (_mkdir(tmpDir) != 0) - return NULL; -#elif defined(__MINGW32__) - if (mkdir(tmpDir) != 0) - return NULL; -#elif defined(__WATCOMC__) && !defined(__LINUX__) - if (mkdir(tmpDir) != 0) - return NULL; -#else - if (mkdir(tmpDir, 0700) != 0) - return NULL; -#endif - - return tmpDir; -} - -int rem_dir(const char* dirName) -{ -#ifdef _MSC_VER - if (_rmdir(dirName) != 0) - return -1; -#else - if (rmdir(dirName) != 0) - return -1; -#endif - return 0; -} - -int rem_file(const char* fileName) -{ -#ifdef _MSC_VER - if (_unlink(fileName) != 0) - return -1; -#else - if (unlink(fileName) != 0) - return -1; -#endif - return 0; -} - -int copy_file(const char* in, const char* out) -{ - byte buf[100]; - XFILE inFile = XBADFILE; - XFILE outFile = XBADFILE; - size_t sz; - int ret = -1; - - inFile = XFOPEN(in, "rb"); - if (inFile == XBADFILE) - goto cleanup; - - outFile = XFOPEN(out, "wb"); - if (outFile == XBADFILE) - goto cleanup; - - while ((sz = XFREAD(buf, 1, sizeof(buf), inFile)) != 0) { - if (XFERROR(inFile)) - goto cleanup; - if (XFWRITE(buf, 1, sz, outFile) != sz) - goto cleanup; - if (XFEOF(inFile)) - break; - } - - ret = 0; -cleanup: - if (inFile != XBADFILE) - XFCLOSE(inFile); - if (outFile != XBADFILE) - XFCLOSE(outFile); - return ret; -} - -#if defined(__MACH__) || defined(__FreeBSD__) -int link_file(const char* in, const char* out) -{ - return link(in, out); -} -#endif -#endif /* !NO_FILESYSTEM */ +#ifndef TESTS_UTILS_H +#define TESTS_UTILS_H +#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && !defined(NO_RSA) && \ + !defined(NO_WOLFSSL_SERVER) && !defined(NO_WOLFSSL_CLIENT) && \ + (!defined(WOLFSSL_NO_TLS12) || defined(WOLFSSL_TLS13)) +#define HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES #define TEST_MEMIO_BUF_SZ (64 * 1024) struct test_memio_ctx { @@ -143,6 +41,8 @@ struct test_memio_ctx int s_len; const char* s_ciphers; }; +int test_memio_write_cb(WOLFSSL *ssl, char *data, int sz, void *ctx); +int test_memio_read_cb(WOLFSSL *ssl, char *data, int sz, void *ctx); int test_memio_do_handshake(WOLFSSL *ssl_c, WOLFSSL *ssl_s, int max_rounds, int *rounds); int test_memio_setup(struct test_memio_ctx *ctx, @@ -153,58 +53,6 @@ int test_memio_setup_ex(struct test_memio_ctx *ctx, method_provider method_c, method_provider method_s, byte *caCert, int caCertSz, byte *serverCert, int serverCertSz, byte *serverKey, int serverKeySz); - -#if !defined(SINGLE_THREADED) && defined(WOLFSSL_COND) -void signal_ready(tcp_ready* ready) -{ - THREAD_CHECK_RET(wolfSSL_CondStart(&ready->cond)); - ready->ready = 1; - THREAD_CHECK_RET(wolfSSL_CondSignal(&ready->cond)); - THREAD_CHECK_RET(wolfSSL_CondEnd(&ready->cond)); -} #endif -void wait_tcp_ready(func_args* args) -{ -#if !defined(SINGLE_THREADED) && defined(WOLFSSL_COND) - tcp_ready* ready = args->signal; - THREAD_CHECK_RET(wolfSSL_CondStart(&ready->cond)); - if (!ready->ready) { - THREAD_CHECK_RET(wolfSSL_CondWait(&ready->cond)); - } - ready->ready = 0; /* reset */ - THREAD_CHECK_RET(wolfSSL_CondEnd(&ready->cond)); -#else - /* no threading wait or single threaded */ - (void)args; -#endif -} - -#ifndef SINGLE_THREADED -/* Start a thread. - * - * @param [in] fun Function to execute in thread. - * @param [in] args Object to send to function in thread. - * @param [out] thread Handle to thread. - */ -void start_thread(THREAD_CB fun, func_args* args, THREAD_TYPE* thread) -{ - THREAD_CHECK_RET(wolfSSL_NewThread(thread, fun, args)); -} - - -/* Join thread to wait for completion. - * - * @param [in] thread Handle to thread. - */ -void join_thread(THREAD_TYPE thread) -{ - THREAD_CHECK_RET(wolfSSL_JoinThread(thread)); -} -#endif /* SINGLE_THREADED */ - -/* These correspond to WOLFSSL_SSLV3...WOLFSSL_DTLSV1_3 */ -const char* tls_desc[] = { - "SSLv3", "TLSv1.0", "TLSv1.1", "TLSv1.2", "TLSv1.3", - "DTLSv1.0", "DTLSv1.2", "DTLSv1.3" -}; +#endif /* TESTS_UTILS_H */ diff --git a/testsuite/include.am b/testsuite/include.am index 7b7cddd03..c96c79cbf 100644 --- a/testsuite/include.am +++ b/testsuite/include.am @@ -20,6 +20,7 @@ endif EXTRA_DIST += testsuite/testsuite.sln EXTRA_DIST += testsuite/testsuite.vcproj EXTRA_DIST += testsuite/testsuite.vcxproj +EXTRA_DIST += testsuite/utils.h EXTRA_DIST += input EXTRA_DIST += quit DISTCLEANFILES+= testsuite/.libs/testsuite.test diff --git a/testsuite/testsuite.c b/testsuite/testsuite.c index 5ca502320..162338c6f 100644 --- a/testsuite/testsuite.c +++ b/testsuite/testsuite.c @@ -52,7 +52,9 @@ #include #include -#include "tests/utils.h" +#include +/* include source file to not change all the testsuite build systems */ +#include #ifndef NO_SHA256 void file_test(const char* file, byte* check); diff --git a/testsuite/utils.c b/testsuite/utils.c new file mode 100644 index 000000000..931eb2dd2 --- /dev/null +++ b/testsuite/utils.c @@ -0,0 +1,191 @@ +/* utils.c + * + * Copyright (C) 2006-2025 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 + */ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#if !defined(WOLFSSL_USER_SETTINGS) && !defined(WOLFSSL_NO_OPTIONS_H) + #include +#endif +#include + +#include +#include +#include + +#ifndef NO_FILESYSTEM + +#if defined(_MSC_VER) +#include +#elif defined(__WATCOMC__) +#ifdef __LINUX__ +#include +#else +#include +#endif +#endif + +#define TMP_DIR_PREFIX "tmpDir-" +/* len is length of tmpDir name, assuming + * len does not include null terminating character */ +char* create_tmp_dir(char *tmpDir, int len) +{ + if (len < (int)XSTR_SIZEOF(TMP_DIR_PREFIX)) + return NULL; + + XMEMCPY(tmpDir, TMP_DIR_PREFIX, XSTR_SIZEOF(TMP_DIR_PREFIX)); + + if (mymktemp(tmpDir, len, len - (int)XSTR_SIZEOF(TMP_DIR_PREFIX)) == NULL) + return NULL; + +#ifdef _MSC_VER + if (_mkdir(tmpDir) != 0) + return NULL; +#elif defined(__MINGW32__) + if (mkdir(tmpDir) != 0) + return NULL; +#elif defined(__WATCOMC__) && !defined(__LINUX__) + if (mkdir(tmpDir) != 0) + return NULL; +#else + if (mkdir(tmpDir, 0700) != 0) + return NULL; +#endif + + return tmpDir; +} + +int rem_dir(const char* dirName) +{ +#ifdef _MSC_VER + if (_rmdir(dirName) != 0) + return -1; +#else + if (rmdir(dirName) != 0) + return -1; +#endif + return 0; +} + +int rem_file(const char* fileName) +{ +#ifdef _MSC_VER + if (_unlink(fileName) != 0) + return -1; +#else + if (unlink(fileName) != 0) + return -1; +#endif + return 0; +} + +int copy_file(const char* in, const char* out) +{ + byte buf[100]; + XFILE inFile = XBADFILE; + XFILE outFile = XBADFILE; + size_t sz; + int ret = -1; + + inFile = XFOPEN(in, "rb"); + if (inFile == XBADFILE) + goto cleanup; + + outFile = XFOPEN(out, "wb"); + if (outFile == XBADFILE) + goto cleanup; + + while ((sz = XFREAD(buf, 1, sizeof(buf), inFile)) != 0) { + if (XFERROR(inFile)) + goto cleanup; + if (XFWRITE(buf, 1, sz, outFile) != sz) + goto cleanup; + if (XFEOF(inFile)) + break; + } + + ret = 0; +cleanup: + if (inFile != XBADFILE) + XFCLOSE(inFile); + if (outFile != XBADFILE) + XFCLOSE(outFile); + return ret; +} + +#if defined(__MACH__) || defined(__FreeBSD__) +int link_file(const char* in, const char* out) +{ + return link(in, out); +} +#endif +#endif /* !NO_FILESYSTEM */ + +#if !defined(SINGLE_THREADED) && defined(WOLFSSL_COND) +void signal_ready(tcp_ready* ready) +{ + THREAD_CHECK_RET(wolfSSL_CondStart(&ready->cond)); + ready->ready = 1; + THREAD_CHECK_RET(wolfSSL_CondSignal(&ready->cond)); + THREAD_CHECK_RET(wolfSSL_CondEnd(&ready->cond)); +} +#endif + +void wait_tcp_ready(func_args* args) +{ +#if !defined(SINGLE_THREADED) && defined(WOLFSSL_COND) + tcp_ready* ready = args->signal; + THREAD_CHECK_RET(wolfSSL_CondStart(&ready->cond)); + if (!ready->ready) { + THREAD_CHECK_RET(wolfSSL_CondWait(&ready->cond)); + } + ready->ready = 0; /* reset */ + THREAD_CHECK_RET(wolfSSL_CondEnd(&ready->cond)); +#else + /* no threading wait or single threaded */ + (void)args; +#endif +} + +#ifndef SINGLE_THREADED +/* Start a thread. + * + * @param [in] fun Function to execute in thread. + * @param [in] args Object to send to function in thread. + * @param [out] thread Handle to thread. + */ +void start_thread(THREAD_CB fun, func_args* args, THREAD_TYPE* thread) +{ + THREAD_CHECK_RET(wolfSSL_NewThread(thread, fun, args)); +} + + +/* Join thread to wait for completion. + * + * @param [in] thread Handle to thread. + */ +void join_thread(THREAD_TYPE thread) +{ + THREAD_CHECK_RET(wolfSSL_JoinThread(thread)); +} +#endif /* SINGLE_THREADED */ + diff --git a/testsuite/utils.h b/testsuite/utils.h new file mode 100644 index 000000000..696ef4d06 --- /dev/null +++ b/testsuite/utils.h @@ -0,0 +1,40 @@ +/* utils.h + * + * Copyright (C) 2006-2025 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 + */ + +/* This is a set of utility functions that are used by testsuite.c. They are + * also used in api.c but we want to keep the utils for testsuite.c as small + * as possible. */ + +#ifndef TESTSUITE_UTILS_H +#define TESTSUITE_UTILS_H + +/* Return + * tmpDir on success + * NULL on failure */ +char* create_tmp_dir(char* tmpDir, int len); +/* Remaining functions return + * 0 on success + * -1 on failure */ +int rem_dir(const char* dirName); +int rem_file(const char* fileName); +int copy_file(const char* in, const char* out); + +#endif /* TESTSUITE_UTILS_H */ diff --git a/wolfssl/test.h b/wolfssl/test.h index f7ef396b7..1a133f2c8 100644 --- a/wolfssl/test.h +++ b/wolfssl/test.h @@ -680,16 +680,6 @@ void test_wolfSSL_client_server_nofail_ex(callback_functions* client_cb, void test_wolfSSL_client_server_nofail(callback_functions* client_cb, callback_functions* server_cb); -/* Return - * tmpDir on success - * NULL on failure */ -char* create_tmp_dir(char* tmpDir, int len); -/* Remaining functions return - * 0 on success - * -1 on failure */ -int rem_dir(const char* dirName); -int rem_file(const char* fileName); -int copy_file(const char* in, const char* out); #if defined(__MACH__) || defined(__FreeBSD__) int link_file(const char* in, const char* out); From 68c27c4e5d5b6625a7bd595eb2d2727f6be9ff71 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Mon, 10 Feb 2025 13:57:06 +0100 Subject: [PATCH 02/10] Move dtls cid tests to tests/api/dtls.c --- tests/api.c | 515 +------------------------------------- tests/api/include.am | 2 + tests/api/test_dtls.c | 557 ++++++++++++++++++++++++++++++++++++++++++ tests/api/test_dtls.h | 29 +++ 4 files changed, 589 insertions(+), 514 deletions(-) create mode 100644 tests/api/test_dtls.c create mode 100644 tests/api/test_dtls.h diff --git a/tests/api.c b/tests/api.c index 4733d790c..75c319664 100644 --- a/tests/api.c +++ b/tests/api.c @@ -300,6 +300,7 @@ #include #include #include +#include #if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && !defined(NO_TLS) && \ !defined(NO_RSA) && !defined(SINGLE_THREADED) && \ @@ -96562,488 +96563,6 @@ static int test_dtls_old_seq_number(void) return EXPECT_RESULT(); } -static int test_dtls12_basic_connection_id(void) -{ - EXPECT_DECLS; -#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && defined(WOLFSSL_DTLS_CID) - unsigned char client_cid[] = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }; - unsigned char server_cid[] = { 0, 1, 2, 3, 4, 5 }; - unsigned char readBuf[40]; - const char* params[] = { -#ifndef NO_RSA -#ifndef NO_SHA256 -#if defined(WOLFSSL_AES_128) && defined(WOLFSSL_STATIC_RSA) - "AES128-SHA256", -#ifdef HAVE_AESCCM - "AES128-CCM8", -#endif - "DHE-RSA-AES128-SHA256", - "ECDHE-RSA-AES128-SHA256", -#ifdef HAVE_AESGCM - "DHE-RSA-AES128-GCM-SHA256", - "ECDHE-RSA-AES128-GCM-SHA256", -#endif -#endif /* WOLFSSL_AES_128 && WOLFSSL_STATIC_RSA */ -#endif /* NO_SHA256 */ -#endif /* NO_RSA */ -#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305) && !defined(HAVE_FIPS) - "DHE-RSA-CHACHA20-POLY1305", - "DHE-RSA-CHACHA20-POLY1305-OLD", - "ECDHE-RSA-CHACHA20-POLY1305", - "ECDHE-RSA-CHACHA20-POLY1305-OLD", -#endif -#ifndef NO_PSK - "DHE-PSK-AES128-CBC-SHA256", - "DHE-PSK-AES256-GCM-SHA384", -#ifdef HAVE_NULL_CIPHER - "DHE-PSK-NULL-SHA256", -#endif - "DHE-PSK-AES128-CCM", -#endif - }; - size_t i; - struct { - byte drop:1; - byte changeCID:1; - } run_params[] = { - { .drop = 0, .changeCID = 0 }, - { .drop = 1, .changeCID = 0 }, - { .drop = 0, .changeCID = 1 }, - }; - - /* We check if the side included the CID in their output */ -#define CLIENT_CID() mymemmem(test_ctx.s_buff, test_ctx.s_len, \ - client_cid, sizeof(client_cid)) -#define SERVER_CID() mymemmem(test_ctx.c_buff, test_ctx.c_len, \ - server_cid, sizeof(server_cid)) - - printf("\n"); - for (i = 0; i < XELEM_CNT(params) && EXPECT_SUCCESS(); i++) { - size_t j; - for (j = 0; j < XELEM_CNT(run_params); j++) { - WOLFSSL_CTX *ctx_c = NULL, *ctx_s = NULL; - WOLFSSL *ssl_c = NULL, *ssl_s = NULL; - struct test_memio_ctx test_ctx; - - printf("Testing %s run #%ld ... ", params[i], (long int)j); - - XMEMSET(&test_ctx, 0, sizeof(test_ctx)); - - ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, - &ssl_s, wolfDTLSv1_2_client_method, wolfDTLSv1_2_server_method), - 0); - - ExpectIntEQ(wolfSSL_set_cipher_list(ssl_c, params[i]), 1); - ExpectIntEQ(wolfSSL_set_cipher_list(ssl_s, params[i]), 1); - - ExpectIntEQ(wolfSSL_dtls_cid_use(ssl_c), 1); - ExpectIntEQ(wolfSSL_dtls_cid_set(ssl_c, server_cid, - sizeof(server_cid)), 1); - ExpectIntEQ(wolfSSL_dtls_cid_use(ssl_s), 1); - ExpectIntEQ(wolfSSL_dtls_cid_set(ssl_s, client_cid, - sizeof(client_cid)), 1); - -#ifndef NO_PSK - if (XSTRSTR(params[i], "-PSK-") != NULL) { - wolfSSL_set_psk_client_callback(ssl_c, my_psk_client_cb); - wolfSSL_set_psk_server_callback(ssl_s, my_psk_server_cb); - } -#endif - -#ifdef HAVE_SECURE_RENEGOTIATION - ExpectIntEQ(wolfSSL_UseSecureRenegotiation(ssl_c), 1); - ExpectIntEQ(wolfSSL_UseSecureRenegotiation(ssl_s), 1); -#endif - - /* CH1 */ - wolfSSL_SetLoggingPrefix("client"); - ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1); - ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ); - ExpectNull(CLIENT_CID()); - if (run_params[j].drop) { - test_ctx.c_len = test_ctx.s_len = 0; - ExpectIntEQ(wolfSSL_dtls_got_timeout(ssl_c), 1); - ExpectNull(CLIENT_CID()); - } - /* HVR */ - wolfSSL_SetLoggingPrefix("server"); - ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1); - ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ); - ExpectNull(SERVER_CID()); - /* No point dropping HVR */ - /* CH2 */ - wolfSSL_SetLoggingPrefix("client"); - ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1); - ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ); - ExpectNull(CLIENT_CID()); - if (run_params[j].drop) { - test_ctx.c_len = test_ctx.s_len = 0; - ExpectIntEQ(wolfSSL_dtls_got_timeout(ssl_c), 1); - ExpectNull(CLIENT_CID()); - } - /* Server first flight */ - wolfSSL_SetLoggingPrefix("server"); - ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1); - ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ); - ExpectNull(SERVER_CID()); - if (run_params[j].drop) { - test_ctx.c_len = test_ctx.s_len = 0; - ExpectIntEQ(wolfSSL_dtls_got_timeout(ssl_s), 1); - ExpectNull(SERVER_CID()); - } - /* Client second flight */ - wolfSSL_SetLoggingPrefix("client"); - ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1); - ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ); - ExpectNotNull(CLIENT_CID()); - if (run_params[j].drop) { - test_ctx.c_len = test_ctx.s_len = 0; - ExpectIntEQ(wolfSSL_dtls_got_timeout(ssl_c), 1); - ExpectNotNull(CLIENT_CID()); - } - /* Server second flight */ - wolfSSL_SetLoggingPrefix("server"); - ExpectIntEQ(wolfSSL_negotiate(ssl_s), 1); - ExpectNotNull(SERVER_CID()); - if (run_params[j].drop) { - test_ctx.c_len = test_ctx.s_len = 0; - ExpectIntEQ(wolfSSL_dtls_got_timeout(ssl_s), 1); - ExpectNotNull(SERVER_CID()); - } - /* Client complete connection */ - wolfSSL_SetLoggingPrefix("client"); - ExpectIntEQ(wolfSSL_negotiate(ssl_c), 1); - ExpectNull(CLIENT_CID()); - - /* Write some data */ - wolfSSL_SetLoggingPrefix("client"); - ExpectIntEQ(wolfSSL_write(ssl_c, params[i], - (int)XSTRLEN(params[i])), XSTRLEN(params[i])); - ExpectNotNull(CLIENT_CID()); - wolfSSL_SetLoggingPrefix("server"); - ExpectIntEQ(wolfSSL_write(ssl_s, params[i], - (int)XSTRLEN(params[i])), XSTRLEN(params[i])); - ExpectNotNull(SERVER_CID()); - /* Read the data */ - wolfSSL_SetLoggingPrefix("client"); - XMEMSET(readBuf, 0, sizeof(readBuf)); - ExpectIntEQ(wolfSSL_read(ssl_c, readBuf, sizeof(readBuf)), - XSTRLEN(params[i])); - ExpectStrEQ(readBuf, params[i]); - XMEMSET(readBuf, 0, sizeof(readBuf)); - wolfSSL_SetLoggingPrefix("server"); - ExpectIntEQ(wolfSSL_read(ssl_s, readBuf, sizeof(readBuf)), - XSTRLEN(params[i])); - ExpectStrEQ(readBuf, params[i]); - /* Write short data */ - wolfSSL_SetLoggingPrefix("client"); - ExpectIntEQ(wolfSSL_write(ssl_c, params[i], 1), 1); - ExpectNotNull(CLIENT_CID()); - wolfSSL_SetLoggingPrefix("server"); - ExpectIntEQ(wolfSSL_write(ssl_s, params[i], 1), 1); - ExpectNotNull(SERVER_CID()); - /* Read the short data */ - XMEMSET(readBuf, 0, sizeof(readBuf)); - wolfSSL_SetLoggingPrefix("client"); - ExpectIntEQ(wolfSSL_read(ssl_c, readBuf, sizeof(readBuf)), 1); - ExpectIntEQ(readBuf[0], params[i][0]); - XMEMSET(readBuf, 0, sizeof(readBuf)); - wolfSSL_SetLoggingPrefix("server"); - ExpectIntEQ(wolfSSL_read(ssl_s, readBuf, sizeof(readBuf)), 1); - ExpectIntEQ(readBuf[0], params[i][0]); - -#ifdef HAVE_SECURE_RENEGOTIATION - /* do two SCR's */ - wolfSSL_SetLoggingPrefix("client"); - ExpectIntEQ(wolfSSL_Rehandshake(ssl_c), -1); - ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ); - ExpectIntEQ(wolfSSL_read(ssl_s, readBuf, sizeof(readBuf)), -1); - ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ); - ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0); - /* SCR's after the first one have extra internal logic */ - wolfSSL_SetLoggingPrefix("client"); - ExpectIntEQ(wolfSSL_Rehandshake(ssl_c), -1); - ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ); - ExpectIntEQ(wolfSSL_read(ssl_s, readBuf, sizeof(readBuf)), -1); - ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ); - ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0); - - if (run_params[j].changeCID) { - ExpectIntEQ(wolfSSL_dtls_cid_set(ssl_c, client_cid, - sizeof(client_cid)), 0); - /* Forcefully change the CID */ - ssl_c->dtlsCidInfo->rx->id[0] = -1; - /* We need to init the rehandshake from the client, otherwise - * we won't be able to test changing the CID. It would be - * rejected by the record CID matching code. */ - wolfSSL_SetLoggingPrefix("client"); - ExpectIntEQ(wolfSSL_Rehandshake(ssl_c), -1); - ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), - WOLFSSL_ERROR_WANT_READ); - ExpectNotNull(CLIENT_CID()); - ExpectIntEQ(wolfSSL_SSL_renegotiate_pending(ssl_c), 1); - /* Server first flight */ - wolfSSL_SetLoggingPrefix("server"); - ExpectIntEQ(wolfSSL_read(ssl_s, readBuf, sizeof(readBuf)), -1); - /* We expect the server to reject the CID change. */ - ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), DTLS_CID_ERROR); - goto loop_exit; - } - /* Server init'd SCR */ - /* Server request */ - wolfSSL_SetLoggingPrefix("server"); - ExpectIntEQ(wolfSSL_Rehandshake(ssl_s), -1); - ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ); - ExpectNotNull(SERVER_CID()); - ExpectIntEQ(wolfSSL_SSL_renegotiate_pending(ssl_s), 1); - if (run_params[j].drop) { - test_ctx.c_len = test_ctx.s_len = 0; - ExpectIntEQ(wolfSSL_dtls_got_timeout(ssl_s), 1); - ExpectNotNull(SERVER_CID()); - } - /* Init SCR on client side with the server's request */ - /* CH no HVR on SCR */ - XMEMSET(readBuf, 0, sizeof(readBuf)); - wolfSSL_SetLoggingPrefix("client"); - ExpectIntEQ(wolfSSL_read(ssl_c, readBuf, sizeof(readBuf)), -1); - ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ); - ExpectNotNull(CLIENT_CID()); - ExpectIntEQ(wolfSSL_SSL_renegotiate_pending(ssl_c), 1); - if (run_params[j].drop) { - test_ctx.c_len = test_ctx.s_len = 0; - ExpectIntEQ(wolfSSL_dtls_got_timeout(ssl_c), 1); - ExpectNotNull(CLIENT_CID()); - } - /* Server first flight */ - wolfSSL_SetLoggingPrefix("server"); - ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1); - ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ); - ExpectNotNull(SERVER_CID()); - if (run_params[j].drop) { - test_ctx.c_len = test_ctx.s_len = 0; - ExpectIntEQ(wolfSSL_dtls_got_timeout(ssl_s), 1); - ExpectNotNull(SERVER_CID()); - } - /* Client second flight */ - wolfSSL_SetLoggingPrefix("client"); - ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1); - ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ); - ExpectNotNull(CLIENT_CID()); - if (run_params[j].drop) { - test_ctx.c_len = test_ctx.s_len = 0; - ExpectIntEQ(wolfSSL_dtls_got_timeout(ssl_c), 1); - ExpectNotNull(CLIENT_CID()); - } - ExpectIntEQ(wolfSSL_write(ssl_c, params[i], - (int)XSTRLEN(params[i])), XSTRLEN(params[i])); - /* Server second flight */ - wolfSSL_SetLoggingPrefix("server"); - ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1); - ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), APP_DATA_READY); - XMEMSET(readBuf, 0, sizeof(readBuf)); - ExpectIntEQ(wolfSSL_read(ssl_s, readBuf, sizeof(readBuf)), - XSTRLEN(params[i])); - ExpectStrEQ(readBuf, params[i]); - if (!run_params[j].drop) { - ExpectIntEQ(wolfSSL_write(ssl_s, params[i], - (int)XSTRLEN(params[i])), XSTRLEN(params[i])); - } - ExpectIntEQ(wolfSSL_negotiate(ssl_s), 1); - ExpectNotNull(SERVER_CID()); - if (run_params[j].drop) { - test_ctx.c_len = test_ctx.s_len = 0; - ExpectIntEQ(wolfSSL_dtls_got_timeout(ssl_s), 1); - ExpectNotNull(SERVER_CID()); - } - /* Test loading old epoch */ - /* Client complete connection */ - wolfSSL_SetLoggingPrefix("client"); - if (!run_params[j].drop) { - ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1); - ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), APP_DATA_READY); - XMEMSET(readBuf, 0, sizeof(readBuf)); - ExpectIntEQ(wolfSSL_read(ssl_c, readBuf, sizeof(readBuf)), - XSTRLEN(params[i])); - ExpectStrEQ(readBuf, params[i]); - } - ExpectIntEQ(wolfSSL_negotiate(ssl_c), 1); - ExpectNull(CLIENT_CID()); - ExpectIntEQ(wolfSSL_SSL_renegotiate_pending(ssl_c), 0); - ExpectIntEQ(wolfSSL_SSL_renegotiate_pending(ssl_s), 0); -#endif - /* Close connection */ - wolfSSL_SetLoggingPrefix("client"); - ExpectIntEQ(wolfSSL_shutdown(ssl_c), WOLFSSL_SHUTDOWN_NOT_DONE); - ExpectNotNull(CLIENT_CID()); - wolfSSL_SetLoggingPrefix("server"); - ExpectIntEQ(wolfSSL_shutdown(ssl_s), WOLFSSL_SHUTDOWN_NOT_DONE); - ExpectNotNull(SERVER_CID()); - wolfSSL_SetLoggingPrefix("client"); - ExpectIntEQ(wolfSSL_shutdown(ssl_c), 1); - wolfSSL_SetLoggingPrefix("server"); - ExpectIntEQ(wolfSSL_shutdown(ssl_s), 1); - -#ifdef HAVE_SECURE_RENEGOTIATION -loop_exit: -#endif - wolfSSL_SetLoggingPrefix(NULL); - wolfSSL_free(ssl_c); - wolfSSL_CTX_free(ctx_c); - wolfSSL_free(ssl_s); - wolfSSL_CTX_free(ctx_s); - - if (EXPECT_SUCCESS()) - printf("ok\n"); - else - printf("failed\n"); - } - - } - -#undef CLIENT_CID -#undef SERVER_CID -#endif - return EXPECT_RESULT(); -} - -static int test_dtls13_basic_connection_id(void) -{ - EXPECT_DECLS; -#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && defined(WOLFSSL_DTLS13) \ - && defined(WOLFSSL_DTLS_CID) - unsigned char client_cid[] = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }; - unsigned char server_cid[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; - unsigned char readBuf[50]; - const char* params[] = { -#ifndef NO_SHA256 -#ifdef WOLFSSL_AES_128 -#ifdef HAVE_AESGCM - "TLS13-AES128-GCM-SHA256", -#endif -#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305) - "TLS13-CHACHA20-POLY1305-SHA256", -#endif -#ifdef HAVE_AESCCM - "TLS13-AES128-CCM-8-SHA256", - "TLS13-AES128-CCM-SHA256", -#endif -#endif -#ifdef HAVE_NULL_CIPHER - "TLS13-SHA256-SHA256", -#endif -#endif - }; - size_t i; - - /* We check if the side included the CID in their output */ -#define CLIENT_CID() mymemmem(test_ctx.s_buff, test_ctx.s_len, \ - client_cid, sizeof(client_cid)) -#define SERVER_CID() mymemmem(test_ctx.c_buff, test_ctx.c_len, \ - server_cid, sizeof(server_cid)) - - printf("\n"); - for (i = 0; i < XELEM_CNT(params) && EXPECT_SUCCESS(); i++) { - WOLFSSL_CTX *ctx_c = NULL, *ctx_s = NULL; - WOLFSSL *ssl_c = NULL, *ssl_s = NULL; - struct test_memio_ctx test_ctx; - - printf("Testing %s ... ", params[i]); - - XMEMSET(&test_ctx, 0, sizeof(test_ctx)); - - ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s, - wolfDTLSv1_3_client_method, wolfDTLSv1_3_server_method), 0); - - ExpectIntEQ(wolfSSL_set_cipher_list(ssl_c, params[i]), WOLFSSL_SUCCESS); - ExpectIntEQ(wolfSSL_set_cipher_list(ssl_s, params[i]), WOLFSSL_SUCCESS); - - ExpectIntEQ(wolfSSL_dtls_cid_use(ssl_c), 1); - ExpectIntEQ(wolfSSL_dtls_cid_set(ssl_c, server_cid, sizeof(server_cid)), - 1); - ExpectIntEQ(wolfSSL_dtls_cid_use(ssl_s), 1); - ExpectIntEQ(wolfSSL_dtls_cid_set(ssl_s, client_cid, sizeof(client_cid)), - 1); - - /* CH1 */ - ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1); - ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ); - ExpectNull(CLIENT_CID()); - /* HRR */ - ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1); - ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ); - ExpectNull(SERVER_CID()); - /* CH2 */ - ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1); - ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ); - ExpectNull(CLIENT_CID()); - /* Server first flight */ - ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1); - ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ); - ExpectNotNull(SERVER_CID()); - /* Client second flight */ - ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1); - ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ); - ExpectNotNull(CLIENT_CID()); - /* Server process flight */ - ExpectIntEQ(wolfSSL_negotiate(ssl_s), 1); - /* Client process flight */ - ExpectIntEQ(wolfSSL_negotiate(ssl_c), 1); - - /* Write some data */ - ExpectIntEQ(wolfSSL_write(ssl_c, params[i], (int)XSTRLEN(params[i])), - XSTRLEN(params[i])); - ExpectNotNull(CLIENT_CID()); - ExpectIntEQ(wolfSSL_write(ssl_s, params[i], (int)XSTRLEN(params[i])), - XSTRLEN(params[i])); - ExpectNotNull(SERVER_CID()); - /* Read the data */ - XMEMSET(readBuf, 0, sizeof(readBuf)); - ExpectIntEQ(wolfSSL_read(ssl_c, readBuf, sizeof(readBuf)), - XSTRLEN(params[i])); - ExpectStrEQ(readBuf, params[i]); - XMEMSET(readBuf, 0, sizeof(readBuf)); - ExpectIntEQ(wolfSSL_read(ssl_s, readBuf, sizeof(readBuf)), - XSTRLEN(params[i])); - ExpectStrEQ(readBuf, params[i]); - /* Write short data */ - ExpectIntEQ(wolfSSL_write(ssl_c, params[i], 1), 1); - ExpectNotNull(CLIENT_CID()); - ExpectIntEQ(wolfSSL_write(ssl_s, params[i], 1), 1); - ExpectNotNull(SERVER_CID()); - /* Read the short data */ - XMEMSET(readBuf, 0, sizeof(readBuf)); - ExpectIntEQ(wolfSSL_read(ssl_c, readBuf, sizeof(readBuf)), 1); - ExpectIntEQ(readBuf[0], params[i][0]); - XMEMSET(readBuf, 0, sizeof(readBuf)); - ExpectIntEQ(wolfSSL_read(ssl_s, readBuf, sizeof(readBuf)), 1); - ExpectIntEQ(readBuf[0], params[i][0]); - - /* Close connection */ - ExpectIntEQ(wolfSSL_shutdown(ssl_c), WOLFSSL_SHUTDOWN_NOT_DONE); - ExpectNotNull(CLIENT_CID()); - ExpectIntEQ(wolfSSL_shutdown(ssl_s), WOLFSSL_SHUTDOWN_NOT_DONE); - ExpectNotNull(SERVER_CID()); - ExpectIntEQ(wolfSSL_shutdown(ssl_c), 1); - ExpectIntEQ(wolfSSL_shutdown(ssl_s), 1); - - if (EXPECT_SUCCESS()) - printf("ok\n"); - else - printf("failed\n"); - - wolfSSL_free(ssl_c); - wolfSSL_CTX_free(ctx_c); - wolfSSL_free(ssl_s); - wolfSSL_CTX_free(ctx_s); - } - -#undef CLIENT_CID -#undef SERVER_CID - -#endif - return EXPECT_RESULT(); -} - static int test_dtls12_missing_finished(void) { EXPECT_DECLS; @@ -98419,38 +97938,6 @@ static int test_wolfSSL_inject(void) return EXPECT_RESULT(); } -static int test_wolfSSL_dtls_cid_parse(void) -{ - EXPECT_DECLS; -#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_DTLS_CID) - /* Taken from Wireshark. Right-click -> copy -> ... as escaped string */ - /* Plaintext ServerHelloDone. No CID. */ - byte noCid[] = - "\x16\xfe\xfd\x00\x00\x00\x00\x00\x00\x00\x04\x00\x0c\x0e\x00\x00" \ - "\x00\x00\x04\x00\x00\x00\x00\x00\x00"; - /* 1.2 app data containing CID */ - byte cid12[] = - "\x19\xfe\xfd\x00\x01\x00\x00\x00\x00\x00\x01\x77\xa3\x79\x34\xb3" \ - "\xf1\x1f\x34\x00\x1f\xdb\x8c\x28\x25\x9f\xe1\x02\x26\x77\x1c\x3a" \ - "\x50\x1b\x50\x99\xd0\xb5\x20\xd8\x2c\x2e\xaa\x36\x36\xe0\xb7\xb7" \ - "\xf7\x7d\xff\xb0"; -#ifdef WOLFSSL_DTLS13 - /* 1.3 app data containing CID */ - byte cid13[] = - "\x3f\x70\x64\x04\xc6\xfb\x97\x21\xd9\x28\x27\x00\x17\xc1\x01\x86" \ - "\xe7\x23\x2c\xad\x65\x83\xa8\xf4\xbf\xbf\x7b\x25\x16\x80\x19\xc3" \ - "\x81\xda\xf5\x3f"; -#endif - - ExpectPtrEq(wolfSSL_dtls_cid_parse(noCid, sizeof(noCid), 8), NULL); - ExpectPtrEq(wolfSSL_dtls_cid_parse(cid12, sizeof(cid12), 8), cid12 + 11); -#ifdef WOLFSSL_DTLS13 - ExpectPtrEq(wolfSSL_dtls_cid_parse(cid13, sizeof(cid13), 8), cid13 + 1); -#endif -#endif - return EXPECT_RESULT(); -} - /*----------------------------------------------------------------------------* | Main *----------------------------------------------------------------------------*/ diff --git a/tests/api/include.am b/tests/api/include.am index 45374b724..445f1207c 100644 --- a/tests/api/include.am +++ b/tests/api/include.am @@ -13,6 +13,7 @@ tests_unit_test_SOURCES += tests/api/test_sm3.c tests_unit_test_SOURCES += tests/api/test_ripemd.c tests_unit_test_SOURCES += tests/api/test_hash.c tests_unit_test_SOURCES += tests/api/test_ascon.c +tests_unit_test_SOURCES += tests/api/test_dtls.c endif EXTRA_DIST += tests/api/api.h EXTRA_DIST += tests/api/test_md5.h @@ -27,4 +28,5 @@ EXTRA_DIST += tests/api/test_hash.h EXTRA_DIST += tests/api/test_ascon.h EXTRA_DIST += tests/api/test_ascon.h EXTRA_DIST += tests/api/test_ascon_kats.h +EXTRA_DIST += tests/api/test_dtls.h diff --git a/tests/api/test_dtls.c b/tests/api/test_dtls.c new file mode 100644 index 000000000..c7f172bfb --- /dev/null +++ b/tests/api/test_dtls.c @@ -0,0 +1,557 @@ +/* dtls.c + * + * Copyright (C) 2006-2025 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 + */ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#if !defined(WOLFSSL_USER_SETTINGS) && !defined(WOLFSSL_NO_OPTIONS_H) + #include +#endif +#include + +#ifdef NO_INLINE + #include +#else + #define WOLFSSL_MISC_INCLUDED + #include +#endif + +#include +#include + +#include +#include +#include + +int test_dtls12_basic_connection_id(void) +{ + EXPECT_DECLS; +#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && defined(WOLFSSL_DTLS_CID) + unsigned char client_cid[] = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }; + unsigned char server_cid[] = { 0, 1, 2, 3, 4, 5 }; + unsigned char readBuf[40]; + const char* params[] = { +#ifndef NO_RSA +#ifndef NO_SHA256 +#if defined(WOLFSSL_AES_128) && defined(WOLFSSL_STATIC_RSA) + "AES128-SHA256", +#ifdef HAVE_AESCCM + "AES128-CCM8", +#endif + "DHE-RSA-AES128-SHA256", + "ECDHE-RSA-AES128-SHA256", +#ifdef HAVE_AESGCM + "DHE-RSA-AES128-GCM-SHA256", + "ECDHE-RSA-AES128-GCM-SHA256", +#endif +#endif /* WOLFSSL_AES_128 && WOLFSSL_STATIC_RSA */ +#endif /* NO_SHA256 */ +#endif /* NO_RSA */ +#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305) && !defined(HAVE_FIPS) + "DHE-RSA-CHACHA20-POLY1305", + "DHE-RSA-CHACHA20-POLY1305-OLD", + "ECDHE-RSA-CHACHA20-POLY1305", + "ECDHE-RSA-CHACHA20-POLY1305-OLD", +#endif +#ifndef NO_PSK + "DHE-PSK-AES128-CBC-SHA256", + "DHE-PSK-AES256-GCM-SHA384", +#ifdef HAVE_NULL_CIPHER + "DHE-PSK-NULL-SHA256", +#endif + "DHE-PSK-AES128-CCM", +#endif + }; + size_t i; + struct { + byte drop:1; + byte changeCID:1; + } run_params[] = { + { .drop = 0, .changeCID = 0 }, + { .drop = 1, .changeCID = 0 }, + { .drop = 0, .changeCID = 1 }, + }; + + /* We check if the side included the CID in their output */ +#define CLIENT_CID() mymemmem(test_ctx.s_buff, test_ctx.s_len, \ + client_cid, sizeof(client_cid)) +#define SERVER_CID() mymemmem(test_ctx.c_buff, test_ctx.c_len, \ + server_cid, sizeof(server_cid)) + + printf("\n"); + for (i = 0; i < XELEM_CNT(params) && EXPECT_SUCCESS(); i++) { + size_t j; + for (j = 0; j < XELEM_CNT(run_params); j++) { + WOLFSSL_CTX *ctx_c = NULL, *ctx_s = NULL; + WOLFSSL *ssl_c = NULL, *ssl_s = NULL; + struct test_memio_ctx test_ctx; + + printf("Testing %s run #%ld ... ", params[i], (long int)j); + + XMEMSET(&test_ctx, 0, sizeof(test_ctx)); + + ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, + &ssl_s, wolfDTLSv1_2_client_method, wolfDTLSv1_2_server_method), + 0); + + ExpectIntEQ(wolfSSL_set_cipher_list(ssl_c, params[i]), 1); + ExpectIntEQ(wolfSSL_set_cipher_list(ssl_s, params[i]), 1); + + ExpectIntEQ(wolfSSL_dtls_cid_use(ssl_c), 1); + ExpectIntEQ(wolfSSL_dtls_cid_set(ssl_c, server_cid, + sizeof(server_cid)), 1); + ExpectIntEQ(wolfSSL_dtls_cid_use(ssl_s), 1); + ExpectIntEQ(wolfSSL_dtls_cid_set(ssl_s, client_cid, + sizeof(client_cid)), 1); + +#ifndef NO_PSK + if (XSTRSTR(params[i], "-PSK-") != NULL) { + wolfSSL_set_psk_client_callback(ssl_c, my_psk_client_cb); + wolfSSL_set_psk_server_callback(ssl_s, my_psk_server_cb); + } +#endif + +#ifdef HAVE_SECURE_RENEGOTIATION + ExpectIntEQ(wolfSSL_UseSecureRenegotiation(ssl_c), 1); + ExpectIntEQ(wolfSSL_UseSecureRenegotiation(ssl_s), 1); +#endif + + /* CH1 */ + wolfSSL_SetLoggingPrefix("client"); + ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1); + ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ); + ExpectNull(CLIENT_CID()); + if (run_params[j].drop) { + test_ctx.c_len = test_ctx.s_len = 0; + ExpectIntEQ(wolfSSL_dtls_got_timeout(ssl_c), 1); + ExpectNull(CLIENT_CID()); + } + /* HVR */ + wolfSSL_SetLoggingPrefix("server"); + ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1); + ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ); + ExpectNull(SERVER_CID()); + /* No point dropping HVR */ + /* CH2 */ + wolfSSL_SetLoggingPrefix("client"); + ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1); + ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ); + ExpectNull(CLIENT_CID()); + if (run_params[j].drop) { + test_ctx.c_len = test_ctx.s_len = 0; + ExpectIntEQ(wolfSSL_dtls_got_timeout(ssl_c), 1); + ExpectNull(CLIENT_CID()); + } + /* Server first flight */ + wolfSSL_SetLoggingPrefix("server"); + ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1); + ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ); + ExpectNull(SERVER_CID()); + if (run_params[j].drop) { + test_ctx.c_len = test_ctx.s_len = 0; + ExpectIntEQ(wolfSSL_dtls_got_timeout(ssl_s), 1); + ExpectNull(SERVER_CID()); + } + /* Client second flight */ + wolfSSL_SetLoggingPrefix("client"); + ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1); + ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ); + ExpectNotNull(CLIENT_CID()); + if (run_params[j].drop) { + test_ctx.c_len = test_ctx.s_len = 0; + ExpectIntEQ(wolfSSL_dtls_got_timeout(ssl_c), 1); + ExpectNotNull(CLIENT_CID()); + } + /* Server second flight */ + wolfSSL_SetLoggingPrefix("server"); + ExpectIntEQ(wolfSSL_negotiate(ssl_s), 1); + ExpectNotNull(SERVER_CID()); + if (run_params[j].drop) { + test_ctx.c_len = test_ctx.s_len = 0; + ExpectIntEQ(wolfSSL_dtls_got_timeout(ssl_s), 1); + ExpectNotNull(SERVER_CID()); + } + /* Client complete connection */ + wolfSSL_SetLoggingPrefix("client"); + ExpectIntEQ(wolfSSL_negotiate(ssl_c), 1); + ExpectNull(CLIENT_CID()); + + /* Write some data */ + wolfSSL_SetLoggingPrefix("client"); + ExpectIntEQ(wolfSSL_write(ssl_c, params[i], + (int)XSTRLEN(params[i])), XSTRLEN(params[i])); + ExpectNotNull(CLIENT_CID()); + wolfSSL_SetLoggingPrefix("server"); + ExpectIntEQ(wolfSSL_write(ssl_s, params[i], + (int)XSTRLEN(params[i])), XSTRLEN(params[i])); + ExpectNotNull(SERVER_CID()); + /* Read the data */ + wolfSSL_SetLoggingPrefix("client"); + XMEMSET(readBuf, 0, sizeof(readBuf)); + ExpectIntEQ(wolfSSL_read(ssl_c, readBuf, sizeof(readBuf)), + XSTRLEN(params[i])); + ExpectStrEQ(readBuf, params[i]); + XMEMSET(readBuf, 0, sizeof(readBuf)); + wolfSSL_SetLoggingPrefix("server"); + ExpectIntEQ(wolfSSL_read(ssl_s, readBuf, sizeof(readBuf)), + XSTRLEN(params[i])); + ExpectStrEQ(readBuf, params[i]); + /* Write short data */ + wolfSSL_SetLoggingPrefix("client"); + ExpectIntEQ(wolfSSL_write(ssl_c, params[i], 1), 1); + ExpectNotNull(CLIENT_CID()); + wolfSSL_SetLoggingPrefix("server"); + ExpectIntEQ(wolfSSL_write(ssl_s, params[i], 1), 1); + ExpectNotNull(SERVER_CID()); + /* Read the short data */ + XMEMSET(readBuf, 0, sizeof(readBuf)); + wolfSSL_SetLoggingPrefix("client"); + ExpectIntEQ(wolfSSL_read(ssl_c, readBuf, sizeof(readBuf)), 1); + ExpectIntEQ(readBuf[0], params[i][0]); + XMEMSET(readBuf, 0, sizeof(readBuf)); + wolfSSL_SetLoggingPrefix("server"); + ExpectIntEQ(wolfSSL_read(ssl_s, readBuf, sizeof(readBuf)), 1); + ExpectIntEQ(readBuf[0], params[i][0]); + +#ifdef HAVE_SECURE_RENEGOTIATION + /* do two SCR's */ + wolfSSL_SetLoggingPrefix("client"); + ExpectIntEQ(wolfSSL_Rehandshake(ssl_c), -1); + ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ); + ExpectIntEQ(wolfSSL_read(ssl_s, readBuf, sizeof(readBuf)), -1); + ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ); + ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0); + /* SCR's after the first one have extra internal logic */ + wolfSSL_SetLoggingPrefix("client"); + ExpectIntEQ(wolfSSL_Rehandshake(ssl_c), -1); + ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ); + ExpectIntEQ(wolfSSL_read(ssl_s, readBuf, sizeof(readBuf)), -1); + ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ); + ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0); + + if (run_params[j].changeCID) { + ExpectIntEQ(wolfSSL_dtls_cid_set(ssl_c, client_cid, + sizeof(client_cid)), 0); + /* Forcefully change the CID */ + ssl_c->dtlsCidInfo->rx->id[0] = -1; + /* We need to init the rehandshake from the client, otherwise + * we won't be able to test changing the CID. It would be + * rejected by the record CID matching code. */ + wolfSSL_SetLoggingPrefix("client"); + ExpectIntEQ(wolfSSL_Rehandshake(ssl_c), -1); + ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), + WOLFSSL_ERROR_WANT_READ); + ExpectNotNull(CLIENT_CID()); + ExpectIntEQ(wolfSSL_SSL_renegotiate_pending(ssl_c), 1); + /* Server first flight */ + wolfSSL_SetLoggingPrefix("server"); + ExpectIntEQ(wolfSSL_read(ssl_s, readBuf, sizeof(readBuf)), -1); + /* We expect the server to reject the CID change. */ + ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), DTLS_CID_ERROR); + goto loop_exit; + } + /* Server init'd SCR */ + /* Server request */ + wolfSSL_SetLoggingPrefix("server"); + ExpectIntEQ(wolfSSL_Rehandshake(ssl_s), -1); + ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ); + ExpectNotNull(SERVER_CID()); + ExpectIntEQ(wolfSSL_SSL_renegotiate_pending(ssl_s), 1); + if (run_params[j].drop) { + test_ctx.c_len = test_ctx.s_len = 0; + ExpectIntEQ(wolfSSL_dtls_got_timeout(ssl_s), 1); + ExpectNotNull(SERVER_CID()); + } + /* Init SCR on client side with the server's request */ + /* CH no HVR on SCR */ + XMEMSET(readBuf, 0, sizeof(readBuf)); + wolfSSL_SetLoggingPrefix("client"); + ExpectIntEQ(wolfSSL_read(ssl_c, readBuf, sizeof(readBuf)), -1); + ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ); + ExpectNotNull(CLIENT_CID()); + ExpectIntEQ(wolfSSL_SSL_renegotiate_pending(ssl_c), 1); + if (run_params[j].drop) { + test_ctx.c_len = test_ctx.s_len = 0; + ExpectIntEQ(wolfSSL_dtls_got_timeout(ssl_c), 1); + ExpectNotNull(CLIENT_CID()); + } + /* Server first flight */ + wolfSSL_SetLoggingPrefix("server"); + ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1); + ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ); + ExpectNotNull(SERVER_CID()); + if (run_params[j].drop) { + test_ctx.c_len = test_ctx.s_len = 0; + ExpectIntEQ(wolfSSL_dtls_got_timeout(ssl_s), 1); + ExpectNotNull(SERVER_CID()); + } + /* Client second flight */ + wolfSSL_SetLoggingPrefix("client"); + ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1); + ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ); + ExpectNotNull(CLIENT_CID()); + if (run_params[j].drop) { + test_ctx.c_len = test_ctx.s_len = 0; + ExpectIntEQ(wolfSSL_dtls_got_timeout(ssl_c), 1); + ExpectNotNull(CLIENT_CID()); + } + ExpectIntEQ(wolfSSL_write(ssl_c, params[i], + (int)XSTRLEN(params[i])), XSTRLEN(params[i])); + /* Server second flight */ + wolfSSL_SetLoggingPrefix("server"); + ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1); + ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), APP_DATA_READY); + XMEMSET(readBuf, 0, sizeof(readBuf)); + ExpectIntEQ(wolfSSL_read(ssl_s, readBuf, sizeof(readBuf)), + XSTRLEN(params[i])); + ExpectStrEQ(readBuf, params[i]); + if (!run_params[j].drop) { + ExpectIntEQ(wolfSSL_write(ssl_s, params[i], + (int)XSTRLEN(params[i])), XSTRLEN(params[i])); + } + ExpectIntEQ(wolfSSL_negotiate(ssl_s), 1); + ExpectNotNull(SERVER_CID()); + if (run_params[j].drop) { + test_ctx.c_len = test_ctx.s_len = 0; + ExpectIntEQ(wolfSSL_dtls_got_timeout(ssl_s), 1); + ExpectNotNull(SERVER_CID()); + } + /* Test loading old epoch */ + /* Client complete connection */ + wolfSSL_SetLoggingPrefix("client"); + if (!run_params[j].drop) { + ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1); + ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), APP_DATA_READY); + XMEMSET(readBuf, 0, sizeof(readBuf)); + ExpectIntEQ(wolfSSL_read(ssl_c, readBuf, sizeof(readBuf)), + XSTRLEN(params[i])); + ExpectStrEQ(readBuf, params[i]); + } + ExpectIntEQ(wolfSSL_negotiate(ssl_c), 1); + ExpectNull(CLIENT_CID()); + ExpectIntEQ(wolfSSL_SSL_renegotiate_pending(ssl_c), 0); + ExpectIntEQ(wolfSSL_SSL_renegotiate_pending(ssl_s), 0); +#endif + /* Close connection */ + wolfSSL_SetLoggingPrefix("client"); + ExpectIntEQ(wolfSSL_shutdown(ssl_c), WOLFSSL_SHUTDOWN_NOT_DONE); + ExpectNotNull(CLIENT_CID()); + wolfSSL_SetLoggingPrefix("server"); + ExpectIntEQ(wolfSSL_shutdown(ssl_s), WOLFSSL_SHUTDOWN_NOT_DONE); + ExpectNotNull(SERVER_CID()); + wolfSSL_SetLoggingPrefix("client"); + ExpectIntEQ(wolfSSL_shutdown(ssl_c), 1); + wolfSSL_SetLoggingPrefix("server"); + ExpectIntEQ(wolfSSL_shutdown(ssl_s), 1); + +#ifdef HAVE_SECURE_RENEGOTIATION +loop_exit: +#endif + wolfSSL_SetLoggingPrefix(NULL); + wolfSSL_free(ssl_c); + wolfSSL_CTX_free(ctx_c); + wolfSSL_free(ssl_s); + wolfSSL_CTX_free(ctx_s); + + if (EXPECT_SUCCESS()) + printf("ok\n"); + else + printf("failed\n"); + } + + } + +#undef CLIENT_CID +#undef SERVER_CID +#endif + return EXPECT_RESULT(); +} + +int test_dtls13_basic_connection_id(void) +{ + EXPECT_DECLS; +#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && defined(WOLFSSL_DTLS13) \ + && defined(WOLFSSL_DTLS_CID) + unsigned char client_cid[] = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }; + unsigned char server_cid[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + unsigned char readBuf[50]; + const char* params[] = { +#ifndef NO_SHA256 +#ifdef WOLFSSL_AES_128 +#ifdef HAVE_AESGCM + "TLS13-AES128-GCM-SHA256", +#endif +#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305) + "TLS13-CHACHA20-POLY1305-SHA256", +#endif +#ifdef HAVE_AESCCM + "TLS13-AES128-CCM-8-SHA256", + "TLS13-AES128-CCM-SHA256", +#endif +#endif +#ifdef HAVE_NULL_CIPHER + "TLS13-SHA256-SHA256", +#endif +#endif + }; + size_t i; + + /* We check if the side included the CID in their output */ +#define CLIENT_CID() mymemmem(test_ctx.s_buff, test_ctx.s_len, \ + client_cid, sizeof(client_cid)) +#define SERVER_CID() mymemmem(test_ctx.c_buff, test_ctx.c_len, \ + server_cid, sizeof(server_cid)) + + printf("\n"); + for (i = 0; i < XELEM_CNT(params) && EXPECT_SUCCESS(); i++) { + WOLFSSL_CTX *ctx_c = NULL, *ctx_s = NULL; + WOLFSSL *ssl_c = NULL, *ssl_s = NULL; + struct test_memio_ctx test_ctx; + + printf("Testing %s ... ", params[i]); + + XMEMSET(&test_ctx, 0, sizeof(test_ctx)); + + ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s, + wolfDTLSv1_3_client_method, wolfDTLSv1_3_server_method), 0); + + ExpectIntEQ(wolfSSL_set_cipher_list(ssl_c, params[i]), WOLFSSL_SUCCESS); + ExpectIntEQ(wolfSSL_set_cipher_list(ssl_s, params[i]), WOLFSSL_SUCCESS); + + ExpectIntEQ(wolfSSL_dtls_cid_use(ssl_c), 1); + ExpectIntEQ(wolfSSL_dtls_cid_set(ssl_c, server_cid, sizeof(server_cid)), + 1); + ExpectIntEQ(wolfSSL_dtls_cid_use(ssl_s), 1); + ExpectIntEQ(wolfSSL_dtls_cid_set(ssl_s, client_cid, sizeof(client_cid)), + 1); + + /* CH1 */ + ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1); + ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ); + ExpectNull(CLIENT_CID()); + /* HRR */ + ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1); + ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ); + ExpectNull(SERVER_CID()); + /* CH2 */ + ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1); + ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ); + ExpectNull(CLIENT_CID()); + /* Server first flight */ + ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1); + ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ); + ExpectNotNull(SERVER_CID()); + /* Client second flight */ + ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1); + ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ); + ExpectNotNull(CLIENT_CID()); + /* Server process flight */ + ExpectIntEQ(wolfSSL_negotiate(ssl_s), 1); + /* Client process flight */ + ExpectIntEQ(wolfSSL_negotiate(ssl_c), 1); + + /* Write some data */ + ExpectIntEQ(wolfSSL_write(ssl_c, params[i], (int)XSTRLEN(params[i])), + XSTRLEN(params[i])); + ExpectNotNull(CLIENT_CID()); + ExpectIntEQ(wolfSSL_write(ssl_s, params[i], (int)XSTRLEN(params[i])), + XSTRLEN(params[i])); + ExpectNotNull(SERVER_CID()); + /* Read the data */ + XMEMSET(readBuf, 0, sizeof(readBuf)); + ExpectIntEQ(wolfSSL_read(ssl_c, readBuf, sizeof(readBuf)), + XSTRLEN(params[i])); + ExpectStrEQ(readBuf, params[i]); + XMEMSET(readBuf, 0, sizeof(readBuf)); + ExpectIntEQ(wolfSSL_read(ssl_s, readBuf, sizeof(readBuf)), + XSTRLEN(params[i])); + ExpectStrEQ(readBuf, params[i]); + /* Write short data */ + ExpectIntEQ(wolfSSL_write(ssl_c, params[i], 1), 1); + ExpectNotNull(CLIENT_CID()); + ExpectIntEQ(wolfSSL_write(ssl_s, params[i], 1), 1); + ExpectNotNull(SERVER_CID()); + /* Read the short data */ + XMEMSET(readBuf, 0, sizeof(readBuf)); + ExpectIntEQ(wolfSSL_read(ssl_c, readBuf, sizeof(readBuf)), 1); + ExpectIntEQ(readBuf[0], params[i][0]); + XMEMSET(readBuf, 0, sizeof(readBuf)); + ExpectIntEQ(wolfSSL_read(ssl_s, readBuf, sizeof(readBuf)), 1); + ExpectIntEQ(readBuf[0], params[i][0]); + + /* Close connection */ + ExpectIntEQ(wolfSSL_shutdown(ssl_c), WOLFSSL_SHUTDOWN_NOT_DONE); + ExpectNotNull(CLIENT_CID()); + ExpectIntEQ(wolfSSL_shutdown(ssl_s), WOLFSSL_SHUTDOWN_NOT_DONE); + ExpectNotNull(SERVER_CID()); + ExpectIntEQ(wolfSSL_shutdown(ssl_c), 1); + ExpectIntEQ(wolfSSL_shutdown(ssl_s), 1); + + if (EXPECT_SUCCESS()) + printf("ok\n"); + else + printf("failed\n"); + + wolfSSL_free(ssl_c); + wolfSSL_CTX_free(ctx_c); + wolfSSL_free(ssl_s); + wolfSSL_CTX_free(ctx_s); + } + +#undef CLIENT_CID +#undef SERVER_CID + +#endif + return EXPECT_RESULT(); +} + +int test_wolfSSL_dtls_cid_parse(void) +{ + EXPECT_DECLS; +#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_DTLS_CID) + /* Taken from Wireshark. Right-click -> copy -> ... as escaped string */ + /* Plaintext ServerHelloDone. No CID. */ + byte noCid[] = + "\x16\xfe\xfd\x00\x00\x00\x00\x00\x00\x00\x04\x00\x0c\x0e\x00\x00" \ + "\x00\x00\x04\x00\x00\x00\x00\x00\x00"; + /* 1.2 app data containing CID */ + byte cid12[] = + "\x19\xfe\xfd\x00\x01\x00\x00\x00\x00\x00\x01\x77\xa3\x79\x34\xb3" \ + "\xf1\x1f\x34\x00\x1f\xdb\x8c\x28\x25\x9f\xe1\x02\x26\x77\x1c\x3a" \ + "\x50\x1b\x50\x99\xd0\xb5\x20\xd8\x2c\x2e\xaa\x36\x36\xe0\xb7\xb7" \ + "\xf7\x7d\xff\xb0"; +#ifdef WOLFSSL_DTLS13 + /* 1.3 app data containing CID */ + byte cid13[] = + "\x3f\x70\x64\x04\xc6\xfb\x97\x21\xd9\x28\x27\x00\x17\xc1\x01\x86" \ + "\xe7\x23\x2c\xad\x65\x83\xa8\xf4\xbf\xbf\x7b\x25\x16\x80\x19\xc3" \ + "\x81\xda\xf5\x3f"; +#endif + + ExpectPtrEq(wolfSSL_dtls_cid_parse(noCid, sizeof(noCid), 8), NULL); + ExpectPtrEq(wolfSSL_dtls_cid_parse(cid12, sizeof(cid12), 8), cid12 + 11); +#ifdef WOLFSSL_DTLS13 + ExpectPtrEq(wolfSSL_dtls_cid_parse(cid13, sizeof(cid13), 8), cid13 + 1); +#endif +#endif + return EXPECT_RESULT(); +} diff --git a/tests/api/test_dtls.h b/tests/api/test_dtls.h new file mode 100644 index 000000000..5944ed7cf --- /dev/null +++ b/tests/api/test_dtls.h @@ -0,0 +1,29 @@ +/* dtls.h + * + * Copyright (C) 2006-2025 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 + */ + +#ifndef TESTS_API_DTLS_H +#define TESTS_API_DTLS_H + +int test_dtls12_basic_connection_id(void); +int test_dtls13_basic_connection_id(void); +int test_wolfSSL_dtls_cid_parse(void); + +#endif /* TESTS_API_DTLS_H */ From 21dce8444811de1a4ae140a80ce441d55c8622b9 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Mon, 10 Feb 2025 14:16:33 +0100 Subject: [PATCH 03/10] Add negative tests for DTLS CID --- tests/api/test_dtls.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/tests/api/test_dtls.c b/tests/api/test_dtls.c index c7f172bfb..2d7305fb1 100644 --- a/tests/api/test_dtls.c +++ b/tests/api/test_dtls.c @@ -231,6 +231,26 @@ int test_dtls12_basic_connection_id(void) wolfSSL_SetLoggingPrefix("server"); ExpectIntEQ(wolfSSL_read(ssl_s, readBuf, sizeof(readBuf)), 1); ExpectIntEQ(readBuf[0], params[i][0]); + /* Write some data but with wrong CID */ + wolfSSL_SetLoggingPrefix("client"); + ExpectIntEQ(wolfSSL_write(ssl_c, params[i], + (int)XSTRLEN(params[i])), XSTRLEN(params[i])); + ExpectNotNull(CLIENT_CID()); + /* Use Expect so we don't access CLIENT_CID() if it is NULL */ + ExpectTrue(((char*)CLIENT_CID())[0] = -1); + wolfSSL_SetLoggingPrefix("server"); + ExpectIntEQ(wolfSSL_write(ssl_s, params[i], + (int)XSTRLEN(params[i])), XSTRLEN(params[i])); + ExpectNotNull(SERVER_CID()); + /* Use Expect so we don't access SERVER_CID() if it is NULL */ + ExpectTrue(((char*)SERVER_CID())[0] = -1); + /* Try to read the data but it shouldn't be there */ + wolfSSL_SetLoggingPrefix("client"); + ExpectIntEQ(wolfSSL_read(ssl_c, readBuf, sizeof(readBuf)), -1); + ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ); + wolfSSL_SetLoggingPrefix("server"); + ExpectIntEQ(wolfSSL_read(ssl_s, readBuf, sizeof(readBuf)), -1); + ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ); #ifdef HAVE_SECURE_RENEGOTIATION /* do two SCR's */ @@ -497,6 +517,22 @@ int test_dtls13_basic_connection_id(void) XMEMSET(readBuf, 0, sizeof(readBuf)); ExpectIntEQ(wolfSSL_read(ssl_s, readBuf, sizeof(readBuf)), 1); ExpectIntEQ(readBuf[0], params[i][0]); + /* Write some data but with wrong CID */ + ExpectIntEQ(wolfSSL_write(ssl_c, params[i], (int)XSTRLEN(params[i])), + XSTRLEN(params[i])); + ExpectNotNull(CLIENT_CID()); + /* Use Expect so we don't access CLIENT_CID() if it is NULL */ + ExpectTrue(((char*)CLIENT_CID())[0] = -1); + ExpectIntEQ(wolfSSL_write(ssl_s, params[i], (int)XSTRLEN(params[i])), + XSTRLEN(params[i])); + ExpectNotNull(SERVER_CID()); + /* Use Expect so we don't access SERVER_CID() if it is NULL */ + ExpectTrue(((char*)SERVER_CID())[0] = -1); + /* Try to read the data but it shouldn't be there */ + ExpectIntEQ(wolfSSL_read(ssl_c, readBuf, sizeof(readBuf)), -1); + ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ); + ExpectIntEQ(wolfSSL_read(ssl_s, readBuf, sizeof(readBuf)), -1); + ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ); /* Close connection */ ExpectIntEQ(wolfSSL_shutdown(ssl_c), WOLFSSL_SHUTDOWN_NOT_DONE); From 301a9a97cc08821c24c9a6ec95ab06a28a92544b Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Mon, 10 Feb 2025 18:29:13 +0100 Subject: [PATCH 04/10] Don't use `buffer` as it can shadow global declarations --- wolfssl/test.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/wolfssl/test.h b/wolfssl/test.h index 1a133f2c8..6b63238a3 100644 --- a/wolfssl/test.h +++ b/wolfssl/test.h @@ -1146,13 +1146,13 @@ static WC_INLINE void ShowX509Chain(WOLFSSL_X509_CHAIN* chain, int count, { int i; int length; - unsigned char buffer[3072]; + unsigned char certPem[3072]; WOLFSSL_X509* chainX509; for (i = 0; i < count; i++) { - wolfSSL_get_chain_cert_pem(chain, i, buffer, sizeof(buffer), &length); - buffer[length] = 0; - printf("\n%s: %d has length %d data = \n%s\n", hdr, i, length, buffer); + wolfSSL_get_chain_cert_pem(chain, i, certPem, sizeof(certPem), &length); + certPem[length] = 0; + printf("\n%s: %d has length %d data = \n%s\n", hdr, i, length, certPem); chainX509 = wolfSSL_get_chain_X509(chain, i); if (chainX509) @@ -2416,7 +2416,7 @@ static THREAD_LS_T int myVerifyAction = VERIFY_OVERRIDE_ERROR; static WC_INLINE int myVerify(int preverify, WOLFSSL_X509_STORE_CTX* store) { - char buffer[WOLFSSL_MAX_ERROR_SZ]; + char err_buffer[WOLFSSL_MAX_ERROR_SZ]; #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) WOLFSSL_X509* peer; #if defined(SHOW_CERTS) && !defined(NO_FILESYSTEM) && \ @@ -2443,7 +2443,7 @@ static WC_INLINE int myVerify(int preverify, WOLFSSL_X509_STORE_CTX* store) */ fprintf(stderr, "In verification callback, error = %d, %s\n", store->error, - wolfSSL_ERR_error_string((unsigned long) store->error, buffer)); + wolfSSL_ERR_error_string((unsigned long) store->error, err_buffer)); #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) peer = store->current_cert; if (peer) { From ede34f132bae9c72d8092e8994496af71e1612a7 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Wed, 12 Feb 2025 09:32:39 +0100 Subject: [PATCH 05/10] fixup! Move dtls cid tests to tests/api/dtls.c --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index fcc5477a0..fbb76d4f6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2500,6 +2500,7 @@ if(WOLFSSL_EXAMPLES) # Build unit tests add_executable(unit_test tests/api.c + tests/api/test_dtls.c tests/api/test_md5.c tests/api/test_sha.c tests/api/test_sha256.c From 825ca22bd8b4b66f3c8904c0e303a590433b1272 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Wed, 12 Feb 2025 10:45:19 +0100 Subject: [PATCH 06/10] Fix cmake build --- CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index fbb76d4f6..773922243 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2517,6 +2517,8 @@ if(WOLFSSL_EXAMPLES) tests/w64wrapper.c tests/unit.c tests/quic.c + tests/utils.c + testsuite/utils.c examples/server/server.c examples/client/client.c) target_include_directories(unit_test PRIVATE From 7380ec68bb92a93b7a4e1000073dd15b1338ea37 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Wed, 12 Feb 2025 10:56:31 +0100 Subject: [PATCH 07/10] cmake.yml: fix error and run tests with ctest --- .github/workflows/cmake.yml | 1 + examples/client/client.c | 2 +- examples/server/server.c | 2 +- src/ssl.c | 19 +++++++++++++++++++ 4 files changed, 22 insertions(+), 2 deletions(-) diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index a2ae9cff4..a3d61ed6a 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -81,6 +81,7 @@ jobs: -DCMAKE_C_FLAGS="-DWOLFSSL_DTLS_CH_FRAG" \ .. cmake --build . + ctest -j $(nproc) cmake --install . # Kyber Cmake broken diff --git a/examples/client/client.c b/examples/client/client.c index 3bd54a6c7..5c2e34053 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -3280,7 +3280,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) #ifdef WOLFSSL_SRTP if (dtlsSrtpProfiles != NULL) { if (wolfSSL_CTX_set_tlsext_use_srtp(ctx, dtlsSrtpProfiles) - != WOLFSSL_SUCCESS) { + != 0) { err_sys("unable to set DTLS SRTP profile"); } } diff --git a/examples/server/server.c b/examples/server/server.c index 5df44d19f..83581ee42 100644 --- a/examples/server/server.c +++ b/examples/server/server.c @@ -2680,7 +2680,7 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) #ifdef WOLFSSL_SRTP if (dtlsSrtpProfiles != NULL) { if (wolfSSL_CTX_set_tlsext_use_srtp(ctx, dtlsSrtpProfiles) - != WOLFSSL_SUCCESS) { + != 0) { err_sys_ex(catastrophic, "unable to set DTLS SRTP profile"); } } diff --git a/src/ssl.c b/src/ssl.c index d684f19a9..9055142ec 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -2152,6 +2152,15 @@ static int DtlsSrtpSelProfiles(word16* id, const char* profile_str) return WOLFSSL_SUCCESS; } +/** + * @brief Set the SRTP protection profiles for DTLS. + * + * @param ctx Pointer to the WOLFSSL_CTX structure representing the SSL/TLS + * context. + * @param profile_str A colon-separated string of SRTP profile names. + * @return 0 on success to match OpenSSL + * @return 1 on error to match OpenSSL + */ int wolfSSL_CTX_set_tlsext_use_srtp(WOLFSSL_CTX* ctx, const char* profile_str) { int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE); @@ -2167,6 +2176,16 @@ int wolfSSL_CTX_set_tlsext_use_srtp(WOLFSSL_CTX* ctx, const char* profile_str) return ret; } + +/** + * @brief Set the SRTP protection profiles for DTLS. + * + * @param ssl Pointer to the WOLFSSL structure representing the SSL/TLS + * session. + * @param profile_str A colon-separated string of SRTP profile names. + * @return 0 on success to match OpenSSL + * @return 1 on error to match OpenSSL + */ int wolfSSL_set_tlsext_use_srtp(WOLFSSL* ssl, const char* profile_str) { int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE); From 3075e572073a1481648a847775cd73fb9ded1f7d Mon Sep 17 00:00:00 2001 From: David Garske Date: Wed, 12 Feb 2025 14:57:00 -0800 Subject: [PATCH 08/10] Whitespace and filename comment. --- src/ssl.c | 12 ++++++------ tests/api/test_dtls.c | 2 +- tests/api/test_dtls.h | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 9055142ec..33ce34a06 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -2178,13 +2178,13 @@ int wolfSSL_CTX_set_tlsext_use_srtp(WOLFSSL_CTX* ctx, const char* profile_str) } /** - * @brief Set the SRTP protection profiles for DTLS. + * @brief Set the SRTP protection profiles for DTLS. * - * @param ssl Pointer to the WOLFSSL structure representing the SSL/TLS - * session. - * @param profile_str A colon-separated string of SRTP profile names. - * @return 0 on success to match OpenSSL - * @return 1 on error to match OpenSSL + * @param ssl Pointer to the WOLFSSL structure representing the SSL/TLS + * session. + * @param profile_str A colon-separated string of SRTP profile names. + * @return 0 on success to match OpenSSL + * @return 1 on error to match OpenSSL */ int wolfSSL_set_tlsext_use_srtp(WOLFSSL* ssl, const char* profile_str) { diff --git a/tests/api/test_dtls.c b/tests/api/test_dtls.c index 2d7305fb1..6de406f10 100644 --- a/tests/api/test_dtls.c +++ b/tests/api/test_dtls.c @@ -1,4 +1,4 @@ -/* dtls.c +/* test_dtls.c * * Copyright (C) 2006-2025 wolfSSL Inc. * diff --git a/tests/api/test_dtls.h b/tests/api/test_dtls.h index 5944ed7cf..68980c3e5 100644 --- a/tests/api/test_dtls.h +++ b/tests/api/test_dtls.h @@ -1,4 +1,4 @@ -/* dtls.h +/* test_dtls.h * * Copyright (C) 2006-2025 wolfSSL Inc. * From cfa6fbfcef28ff41574dc961bdebee0e0a702a10 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Fri, 14 Feb 2025 12:12:29 +0100 Subject: [PATCH 09/10] Correct wolfSSL_dtls_cid_parse declaration in docs --- doc/dox_comments/header_files/ssl.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/dox_comments/header_files/ssl.h b/doc/dox_comments/header_files/ssl.h index 7d7a629f8..7da361348 100644 --- a/doc/dox_comments/header_files/ssl.h +++ b/doc/dox_comments/header_files/ssl.h @@ -15251,8 +15251,8 @@ RFC 9146 and RFC 9147. \sa wolfSSL_dtls_cid_get_rx \sa wolfSSL_dtls_cid_get_tx_size */ -void wolfSSL_dtls_cid_parse(const unsigned char* msg, unsigned int msgSz, - const unsigned char** cid, unsigned int cidSz); +const unsigned char* wolfSSL_dtls_cid_parse(const unsigned char* msg, + unsigned int msgSz, unsigned int cidSz); /*! \ingroup TLS From 690bb14203520e3ac40722f1fe32141a6127a886 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Fri, 14 Feb 2025 10:57:29 -0600 Subject: [PATCH 10/10] tests/utils.c and tests/api/test_dtls.c: fixes for include order, re tests/unit.h. --- tests/api/test_dtls.c | 10 +--------- tests/utils.c | 12 +----------- 2 files changed, 2 insertions(+), 20 deletions(-) diff --git a/tests/api/test_dtls.c b/tests/api/test_dtls.c index 6de406f10..2c8d3c9bb 100644 --- a/tests/api/test_dtls.c +++ b/tests/api/test_dtls.c @@ -19,14 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ -#ifdef HAVE_CONFIG_H - #include -#endif - -#if !defined(WOLFSSL_USER_SETTINGS) && !defined(WOLFSSL_NO_OPTIONS_H) - #include -#endif -#include +#include #ifdef NO_INLINE #include @@ -38,7 +31,6 @@ #include #include -#include #include #include diff --git a/tests/utils.c b/tests/utils.c index bbdd5cf53..2b78b3a67 100644 --- a/tests/utils.c +++ b/tests/utils.c @@ -19,18 +19,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ -#ifdef HAVE_CONFIG_H - #include -#endif - -#if !defined(WOLFSSL_USER_SETTINGS) && !defined(WOLFSSL_NO_OPTIONS_H) - #include -#endif -#include - -#include -#include #include +#include #ifdef HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES