mirror of
https://github.com/OpenVPN/openvpn.git
synced 2024-09-19 19:42:30 +02:00
Add test_ssl unit test and test export of PEM to file
This introduces a number of mock function to be able to compile ssl_verify_*.c and ssl_mbedtls.c/ssl_openssl.c into a unit and adds quite a number of files to that unit. But it allows similar unit tests (in term of dependencies) to be added in the future. Change-Id: Ie248d35d063bb6878f3dd42840c77ba0d6fa3381 Signed-off-by: Arne Schwabe <arne@rfc2549.org> Acked-by: Gert Doering <gert@greenie.muc.de> Message-Id: <20240116214152.27316-1-gert@greenie.muc.de> URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg28028.html Signed-off-by: Gert Doering <gert@greenie.muc.de>
This commit is contained in:
parent
0ce0689391
commit
cedbac710c
2
.github/workflows/build.yaml
vendored
2
.github/workflows/build.yaml
vendored
@ -85,7 +85,7 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
arch: [x86, x64]
|
||||
test: [argv, auth_token, buffer, cryptoapi, crypto, misc, ncp, packet_id, pkt, provider, tls_crypt]
|
||||
test: [argv, auth_token, buffer, cryptoapi, crypto, misc, ncp, packet_id, pkt, provider, ssl, tls_crypt]
|
||||
|
||||
runs-on: windows-latest
|
||||
name: "mingw unittest ${{ matrix.test }} - ${{ matrix.arch }} - OSSL"
|
||||
|
@ -595,6 +595,7 @@ if (BUILD_TESTING)
|
||||
"test_packet_id"
|
||||
"test_pkt"
|
||||
"test_provider"
|
||||
"test_ssl"
|
||||
)
|
||||
|
||||
if (WIN32)
|
||||
@ -699,6 +700,32 @@ if (BUILD_TESTING)
|
||||
src/openvpn/mss.c
|
||||
)
|
||||
|
||||
target_sources(test_ssl PRIVATE
|
||||
tests/unit_tests/openvpn/mock_management.c
|
||||
tests/unit_tests/openvpn/mock_ssl_dependencies.c
|
||||
tests/unit_tests/openvpn/mock_win32_execve.c
|
||||
src/openvpn/argv.c
|
||||
src/openvpn/base64.c
|
||||
src/openvpn/crypto.c
|
||||
src/openvpn/crypto_mbedtls.c
|
||||
src/openvpn/crypto_openssl.c
|
||||
src/openvpn/cryptoapi.c
|
||||
src/openvpn/env_set.c
|
||||
src/openvpn/mss.c
|
||||
src/openvpn/mtu.c
|
||||
src/openvpn/options_util.c
|
||||
src/openvpn/otime.c
|
||||
src/openvpn/packet_id.c
|
||||
src/openvpn/run_command.c
|
||||
src/openvpn/ssl_mbedtls.c
|
||||
src/openvpn/ssl_openssl.c
|
||||
src/openvpn/ssl_util.c
|
||||
src/openvpn/ssl_verify_mbedtls.c
|
||||
src/openvpn/ssl_verify_openssl.c
|
||||
src/openvpn/xkey_helper.c
|
||||
src/openvpn/xkey_provider.c
|
||||
)
|
||||
|
||||
target_sources(test_misc PRIVATE
|
||||
tests/unit_tests/openvpn/mock_get_random.c
|
||||
src/openvpn/options_util.c
|
||||
|
@ -9,7 +9,8 @@ test_binaries += argv_testdriver buffer_testdriver
|
||||
endif
|
||||
|
||||
test_binaries += crypto_testdriver packet_id_testdriver auth_token_testdriver ncp_testdriver misc_testdriver \
|
||||
pkt_testdriver
|
||||
pkt_testdriver ssl_testdriver
|
||||
|
||||
if HAVE_LD_WRAP_SUPPORT
|
||||
if !WIN32
|
||||
test_binaries += tls_crypt_testdriver
|
||||
@ -69,6 +70,40 @@ crypto_testdriver_SOURCES = test_crypto.c mock_msg.c mock_msg.h \
|
||||
$(top_srcdir)/src/openvpn/win32-util.c \
|
||||
$(top_srcdir)/src/openvpn/mss.c
|
||||
|
||||
ssl_testdriver_CFLAGS = @TEST_CFLAGS@ \
|
||||
-I$(top_srcdir)/include -I$(top_srcdir)/src/compat -I$(top_srcdir)/src/openvpn
|
||||
ssl_testdriver_LDFLAGS = @TEST_LDFLAGS@ $(OPTIONAL_CRYPTO_LIBS)
|
||||
ssl_testdriver_SOURCES = test_ssl.c mock_msg.c mock_msg.h \
|
||||
mock_management.c mock_ssl_dependencies.c mock_win32_execve.c \
|
||||
$(top_srcdir)/src/openvpn/argv.c \
|
||||
$(top_srcdir)/src/openvpn/base64.c \
|
||||
$(top_srcdir)/src/openvpn/buffer.c \
|
||||
$(top_srcdir)/src/compat/compat-strsep.c \
|
||||
$(top_srcdir)/src/openvpn/crypto.c \
|
||||
$(top_srcdir)/src/openvpn/cryptoapi.c \
|
||||
$(top_srcdir)/src/openvpn/crypto_mbedtls.c \
|
||||
$(top_srcdir)/src/openvpn/crypto_openssl.c \
|
||||
$(top_srcdir)/src/openvpn/env_set.c \
|
||||
$(top_srcdir)/src/openvpn/mss.c \
|
||||
$(top_srcdir)/src/openvpn/mtu.c \
|
||||
$(top_srcdir)/src/openvpn/otime.c \
|
||||
$(top_srcdir)/src/openvpn/options_util.c \
|
||||
$(top_srcdir)/src/openvpn/packet_id.c \
|
||||
$(top_srcdir)/src/openvpn/platform.c \
|
||||
$(top_srcdir)/src/openvpn/run_command.c \
|
||||
$(top_srcdir)/src/openvpn/ssl_openssl.c \
|
||||
$(top_srcdir)/src/openvpn/ssl_mbedtls.c \
|
||||
$(top_srcdir)/src/openvpn/ssl_util.c \
|
||||
$(top_srcdir)/src/openvpn/ssl_verify_mbedtls.c \
|
||||
$(top_srcdir)/src/openvpn/ssl_verify_openssl.c \
|
||||
$(top_srcdir)/src/openvpn/xkey_helper.c \
|
||||
$(top_srcdir)/src/openvpn/xkey_provider.c \
|
||||
$(top_srcdir)/src/openvpn/win32-util.c
|
||||
|
||||
if WIN32
|
||||
ssl_testdriver_LDADD = -lcrypt32 -lncrypt -lfwpuclnt -liphlpapi -lws2_32
|
||||
endif
|
||||
|
||||
packet_id_testdriver_CFLAGS = @TEST_CFLAGS@ \
|
||||
-I$(top_srcdir)/include -I$(top_srcdir)/src/compat -I$(top_srcdir)/src/openvpn
|
||||
packet_id_testdriver_LDFLAGS = @TEST_LDFLAGS@
|
||||
|
51
tests/unit_tests/openvpn/mock_management.c
Normal file
51
tests/unit_tests/openvpn/mock_management.c
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 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) 2002-2023 OpenVPN Inc <sales@openvpn.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* Minimal set of mocked management function/globals to get unit tests to
|
||||
* compile */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "syshead.h"
|
||||
|
||||
#include "manage.h"
|
||||
|
||||
#ifdef ENABLE_MANAGEMENT
|
||||
|
||||
struct management *management; /* GLOBAL */
|
||||
|
||||
void
|
||||
management_auth_failure(struct management *man, const char *type, const char *reason)
|
||||
{
|
||||
ASSERT(false);
|
||||
}
|
||||
|
||||
char *
|
||||
management_query_pk_sig(struct management *man, const char *b64_data,
|
||||
const char *algorithm)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
67
tests/unit_tests/openvpn/mock_ssl_dependencies.c
Normal file
67
tests/unit_tests/openvpn/mock_ssl_dependencies.c
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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) 2002-2023 OpenVPN Inc <sales@openvpn.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* Minimal set of mocked function/globals to get unit tests to
|
||||
* compile that use the ssl_* files */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "syshead.h"
|
||||
|
||||
#include <setjmp.h>
|
||||
#include <cmocka.h>
|
||||
|
||||
|
||||
#include "ssl.h"
|
||||
#include "ssl_verify.h"
|
||||
|
||||
int
|
||||
parse_line(const char *line, char **p, const int n, const char *file,
|
||||
const int line_num, int msglevel, struct gc_arena *gc)
|
||||
{
|
||||
/* Dummy function to get the linker happy, should never be called */
|
||||
assert_true(false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
pem_password_callback(char *buf, int size, int rwflag, void *u)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
cert_hash_remember(struct tls_session *session, const int cert_depth,
|
||||
const struct buffer *cert_hash)
|
||||
{
|
||||
assert_false(true);
|
||||
}
|
||||
|
||||
result_t
|
||||
verify_cert(struct tls_session *session, openvpn_x509_cert_t *cert, int cert_depth)
|
||||
{
|
||||
return FAILURE;
|
||||
}
|
140
tests/unit_tests/openvpn/test_ssl.c
Normal file
140
tests/unit_tests/openvpn/test_ssl.c
Normal file
@ -0,0 +1,140 @@
|
||||
/*
|
||||
* 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 OpenVPN Inc <sales@openvpn.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* 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"
|
||||
#endif
|
||||
|
||||
#include "syshead.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <setjmp.h>
|
||||
#include <cmocka.h>
|
||||
|
||||
#include "crypto.h"
|
||||
#include "options.h"
|
||||
#include "ssl_backend.h"
|
||||
#include "options_util.h"
|
||||
|
||||
#include "mock_msg.h"
|
||||
#include "mss.h"
|
||||
#include "ssl_verify_backend.h"
|
||||
#include "win32.h"
|
||||
|
||||
/* Mock function to be allowed to include win32.c which is required for
|
||||
* getting the temp directory */
|
||||
#ifdef _WIN32
|
||||
struct signal_info siginfo_static; /* GLOBAL */
|
||||
|
||||
const char *
|
||||
strerror_win32(DWORD errnum, struct gc_arena *gc)
|
||||
{
|
||||
ASSERT(false);
|
||||
}
|
||||
|
||||
void
|
||||
throw_signal(const int signum)
|
||||
{
|
||||
ASSERT(false);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
const char *unittest_cert = "-----BEGIN CERTIFICATE-----\n"
|
||||
"MIIBuTCCAUCgAwIBAgIUTLtjSBzx53qZRvZ6Ur7D9kgoOHkwCgYIKoZIzj0EAwIw\n"
|
||||
"EzERMA8GA1UEAwwIdW5pdHRlc3QwIBcNMjMxMTIxMDk1NDQ3WhgPMjA3ODA4MjQw\n"
|
||||
"OTU0NDdaMBMxETAPBgNVBAMMCHVuaXR0ZXN0MHYwEAYHKoZIzj0CAQYFK4EEACID\n"
|
||||
"YgAEHYB2hn2xx3f4lClXDtdi36P19pMZA+kI1Dkv/Vn10vBZ/j9oa+P99T8duz/e\n"
|
||||
"QlPeHpesNJO4fX8iEDj6+vMeWejOT7jAQ4MmG5EZjpcBKxCfwFooEvzu8bVujUcu\n"
|
||||
"wTQEo1MwUTAdBgNVHQ4EFgQUPcgBEVXjF5vYfDsInoE3dF6UfQswHwYDVR0jBBgw\n"
|
||||
"FoAUPcgBEVXjF5vYfDsInoE3dF6UfQswDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjO\n"
|
||||
"PQQDAgNnADBkAjBLPAGrQAyinigqiu0RomoV8TVaknVLFSq6H6A8jgvzfsFCUK1O\n"
|
||||
"dvNZhFPM6idKB+oCME2JLOBANCSV8o7aJzq7SYHKwPyb1J4JFlwKe/0Jpv7oh9b1\n"
|
||||
"IJbuaM9Z/VSKbrIXGg==\n"
|
||||
"-----END CERTIFICATE-----\n";
|
||||
|
||||
static const char *
|
||||
get_tmp_dir()
|
||||
{
|
||||
const char *ret;
|
||||
#ifdef _WIN32
|
||||
ret = win_get_tempdir();
|
||||
#else
|
||||
ret = "/tmp";
|
||||
#endif
|
||||
assert_non_null(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
crypto_pem_encode_certificate(void **state)
|
||||
{
|
||||
struct gc_arena gc = gc_new();
|
||||
|
||||
struct tls_root_ctx ctx = { 0 };
|
||||
tls_ctx_client_new(&ctx);
|
||||
tls_ctx_load_cert_file(&ctx, unittest_cert, true);
|
||||
|
||||
openvpn_x509_cert_t *cert = NULL;
|
||||
|
||||
/* we do not have methods to fetch certificates from ssl contexts, use
|
||||
* internal TLS library methods for the unit test */
|
||||
#ifdef ENABLE_CRYPTO_OPENSSL
|
||||
cert = SSL_CTX_get0_certificate(ctx.ctx);
|
||||
#elif defined(ENABLE_CRYPTO_MBEDTLS)
|
||||
cert = ctx.crt_chain;
|
||||
#endif
|
||||
|
||||
const char *tmpfile = platform_create_temp_file(get_tmp_dir(), "ut_pem", &gc);
|
||||
backend_x509_write_pem(cert, tmpfile);
|
||||
|
||||
struct buffer exported_pem = buffer_read_from_file(tmpfile, &gc);
|
||||
assert_string_equal(BSTR(&exported_pem), unittest_cert);
|
||||
|
||||
tls_ctx_free(&ctx);
|
||||
unlink(tmpfile);
|
||||
gc_free(&gc);
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
const struct CMUnitTest tests[] = {
|
||||
cmocka_unit_test(crypto_pem_encode_certificate)
|
||||
};
|
||||
|
||||
#if defined(ENABLE_CRYPTO_OPENSSL)
|
||||
OpenSSL_add_all_algorithms();
|
||||
#endif
|
||||
|
||||
int ret = cmocka_run_group_tests_name("crypto tests", tests, NULL, NULL);
|
||||
|
||||
#if defined(ENABLE_CRYPTO_OPENSSL)
|
||||
EVP_cleanup();
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
Loading…
Reference in New Issue
Block a user