diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 162dd8ce..a3ca7a2e 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -243,6 +243,9 @@ jobs: - name: Run bufferunit test run: ./unittests/buffer_testdriver.exe + - name: Run cryptoapi unit test + run: ./unittests/cryptoapi_testdriver.exe + - name: Run cryptounit test run: ./unittests/crypto_testdriver.exe diff --git a/tests/unit_tests/openvpn/Makefile.am b/tests/unit_tests/openvpn/Makefile.am index 8d2386e0..ee0a3d8a 100644 --- a/tests/unit_tests/openvpn/Makefile.am +++ b/tests/unit_tests/openvpn/Makefile.am @@ -17,6 +17,7 @@ endif test_binaries += provider_testdriver if WIN32 +test_binaries += cryptoapi_testdriver LDADD = -lws2_32 endif @@ -152,6 +153,21 @@ provider_testdriver_SOURCES = test_provider.c mock_msg.c \ $(openvpn_srcdir)/win32-util.c \ $(openvpn_srcdir)/platform.c +if WIN32 +cryptoapi_testdriver_CFLAGS = @TEST_CFLAGS@ \ + -I$(openvpn_includedir) -I$(compat_srcdir) -I$(openvpn_srcdir) \ + $(OPTIONAL_CRYPTO_CFLAGS) +cryptoapi_testdriver_LDFLAGS = @TEST_LDFLAGS@ \ + $(OPTIONAL_CRYPTO_LIBS) -lcrypt32 -lncrypt +cryptoapi_testdriver_SOURCES = test_cryptoapi.c mock_msg.c \ + $(openvpn_srcdir)/xkey_helper.c \ + $(openvpn_srcdir)/buffer.c \ + $(openvpn_srcdir)/base64.c \ + $(openvpn_srcdir)/platform.c \ + mock_get_random.c \ + $(openvpn_srcdir)/win32-util.c +endif + auth_token_testdriver_CFLAGS = @TEST_CFLAGS@ \ -I$(openvpn_includedir) -I$(compat_srcdir) -I$(openvpn_srcdir) \ $(OPTIONAL_CRYPTO_CFLAGS) diff --git a/tests/unit_tests/openvpn/test_cryptoapi.c b/tests/unit_tests/openvpn/test_cryptoapi.c new file mode 100644 index 00000000..73ef34e9 --- /dev/null +++ b/tests/unit_tests/openvpn/test_cryptoapi.c @@ -0,0 +1,126 @@ +/* + * OpenVPN -- An application to securely tunnel IP networks + * over a single UDP port, with support for SSL/TLS-based + * session authentication and key exchange, + * packet encryption, packet authentication, and + * packet compression. + * + * Copyright (C) 2023 Selva Nair + * + * This program 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. + * + * This program 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-1301 USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#elif defined(_MSC_VER) +#include "config-msvc.h" +#endif + +#include "syshead.h" +#include "manage.h" +#include "integer.h" +#include "xkey_common.h" + +#if defined(HAVE_XKEY_PROVIDER) && defined (ENABLE_CRYPTOAPI) +#include +#include +#include +#include +#include +#include + +#include +#include /* pull-in the whole file to test static functions */ + +struct management *management; /* global */ + +/* mock a management function that xkey_provider needs */ +char * +management_query_pk_sig(struct management *man, const char *b64_data, + const char *algorithm) +{ + (void) man; + (void) b64_data; + (void) algorithm; + return NULL; +} + +/* tls_libctx is defined in ssl_openssl.c which we do not want to compile in */ +OSSL_LIB_CTX *tls_libctx; + +#ifndef _countof +#define _countof(x) sizeof((x))/sizeof(*(x)) +#endif + +/* test data */ +static const uint8_t test_hash[] = { + 0x77, 0x38, 0x65, 0x00, 0x1e, 0x96, 0x48, 0xc6, 0x57, 0x0b, 0xae, + 0xc0, 0xb7, 0x96, 0xf9, 0x66, 0x4d, 0x5f, 0xd0, 0xb7 +}; + +/* valid test strings to test with and without embedded and trailing spaces */ +static const char *valid_str[] = { + "773865001e9648c6570baec0b796f9664d5fd0b7", + " 77 386500 1e 96 48 c6570b aec0b7 96f9664d5f d0 b7", + " 773865001e9648c6570baec0b796f9664d5fd0b7 ", +}; + +/* some invalid strings to test */ +static const char *invalid_str[] = { + "773 865001e9648c6570baec0b796f9664d5fd0b7", /* space within byte */ + "77:38:65001e9648c6570baec0b796f9664d5fd0b7", /* invalid separator */ + "7738x5001e9648c6570baec0b796f9664d5fd0b7", /* non hex character */ +}; + +static void +test_parse_hexstring(void **state) +{ + unsigned char hash[255]; + (void) state; + + for (int i = 0; i < _countof(valid_str); i++) + { + int len = parse_hexstring(valid_str[i], hash, _countof(hash)); + assert_int_equal(len, sizeof(test_hash)); + assert_memory_equal(hash, test_hash, sizeof(test_hash)); + memset(hash, 0, _countof(hash)); + } + + for (int i = 0; i < _countof(invalid_str); i++) + { + int len = parse_hexstring(invalid_str[i], hash, _countof(hash)); + assert_int_equal(len, 0); + } +} + +int +main(void) +{ + const struct CMUnitTest tests[] = { cmocka_unit_test(test_parse_hexstring) }; + + int ret = cmocka_run_group_tests_name("cryptoapi tests", tests, NULL, NULL); + + return ret; +} + +#else /* ifdef HAVE_XKEY_PROVIDER */ + +int +main(void) +{ + return 0; +} + +#endif /* ifdef HAVE_XKEY_PROVIDER */