summaryrefslogtreecommitdiff
path: root/src/lib/tests
diff options
context:
space:
mode:
authorDimitri Staessens <dimitri@ouroboros.rocks>2025-06-28 11:27:50 +0200
committerSander Vrijders <sander@ouroboros.rocks>2025-07-04 10:12:15 +0200
commit84134b93c1fc1c670f52ab199dcda6fc9c42626f (patch)
tree92375d0d9d656b7ccfb003ba7cf30c54171cd847 /src/lib/tests
parentd2295c1c228f05beaf3ec8abe44a4ae114742076 (diff)
downloadouroboros-84134b93c1fc1c670f52ab199dcda6fc9c42626f.tar.gz
ouroboros-84134b93c1fc1c670f52ab199dcda6fc9c42626f.zip
lib: Add authentication functions
Adds functions needed for authentication using X509 certificates, implemented using OpenSSL. Refactors some library internals, and adds some unit tests for them. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
Diffstat (limited to 'src/lib/tests')
-rw-r--r--src/lib/tests/CMakeLists.txt7
-rw-r--r--src/lib/tests/auth_test.c571
-rw-r--r--src/lib/tests/crypt_test.c256
-rw-r--r--src/lib/tests/sockets_test.c98
-rw-r--r--src/lib/tests/time_test.c6
-rw-r--r--src/lib/tests/tpm_test.c104
6 files changed, 1040 insertions, 2 deletions
diff --git a/src/lib/tests/CMakeLists.txt b/src/lib/tests/CMakeLists.txt
index dc90671b..2791dd0d 100644
--- a/src/lib/tests/CMakeLists.txt
+++ b/src/lib/tests/CMakeLists.txt
@@ -3,14 +3,18 @@ get_filename_component(PARENT_DIR ${PARENT_PATH} NAME)
create_test_sourcelist(${PARENT_DIR}_tests test_suite.c
# Add new tests here
+ auth_test.c
bitmap_test.c
btree_test.c
crc32_test.c
+ crypt_test.c
hash_test.c
md5_test.c
sha3_test.c
shm_rbuff_test.c
+ sockets_test.c
time_test.c
+ tpm_test.c
)
add_executable(${PARENT_DIR}_test EXCLUDE_FROM_ALL ${${PARENT_DIR}_tests})
@@ -30,3 +34,6 @@ foreach (test ${tests_to_run})
get_filename_component(test_name ${test} NAME_WE)
add_test(${test_name} ${C_TEST_PATH}/${PARENT_DIR}_test ${test_name})
endforeach (test)
+
+set_property(TEST auth_test PROPERTY SKIP_RETURN_CODE 1)
+set_property(TEST crypt_test PROPERTY SKIP_RETURN_CODE 1)
diff --git a/src/lib/tests/auth_test.c b/src/lib/tests/auth_test.c
new file mode 100644
index 00000000..5fabfbd4
--- /dev/null
+++ b/src/lib/tests/auth_test.c
@@ -0,0 +1,571 @@
+/*
+ * Ouroboros - Copyright (C) 2016 - 2024
+ *
+ * Test of the authentication functions
+ *
+ * Dimitri Staessens <dimitri@ouroboros.rocks>
+ * Sander Vrijders <sander@ouroboros.rocks>
+ *
+ * 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., http://www.fsf.org/about/contact/.
+ */
+
+#include "config.h"
+
+#include <ouroboros/test.h>
+#include <ouroboros/crypt.h>
+#include <ouroboros/random.h>
+#include <ouroboros/utils.h>
+
+#define TEST_MSG_SIZE 1500
+
+/*
+* Certificates created following the guide
+* Building an openssl certificate authority
+* on
+* https://community.f5.com/kb/technicalarticles/
+*/
+
+/* Root certificate for CA ca.unittest.o7s */
+static const char * root_ca_crt = \
+"-----BEGIN CERTIFICATE-----\n"
+"MIICiTCCAi6gAwIBAgIUbTYRdvvGJpI99I3ag0Epj8PzOHwwCwYJYIZIAWUDBAMK\n"
+"MIGQMQswCQYDVQQGEwJCRTEMMAoGA1UECAwDT1ZMMQ4wDAYDVQQHDAVHaGVudDEM\n"
+"MAoGA1UECgwDbzdzMRUwEwYDVQQLDAx1bml0dGVzdC5vN3MxGDAWBgNVBAMMD2Nh\n"
+"LnVuaXR0ZXN0Lm83czEkMCIGCSqGSIb3DQEJARYVZHVtbXlAb3Vyb2Jvcm9zLnJv\n"
+"Y2tzMB4XDTI1MDYyMjEzNDcwOVoXDTI1MDcyMjEzNDcwOVowgZAxCzAJBgNVBAYT\n"
+"AkJFMQwwCgYDVQQIDANPVkwxDjAMBgNVBAcMBUdoZW50MQwwCgYDVQQKDANvN3Mx\n"
+"FTATBgNVBAsMDHVuaXR0ZXN0Lm83czEYMBYGA1UEAwwPY2EudW5pdHRlc3Qubzdz\n"
+"MSQwIgYJKoZIhvcNAQkBFhVkdW1teUBvdXJvYm9yb3Mucm9ja3MwWTATBgcqhkjO\n"
+"PQIBBggqhkjOPQMBBwNCAATsvzzYnXYQuZVMA7ckGEb8KISyHhXCBmc/kVcRyAje\n"
+"hVq+F6nuWEEJVy/zNyMdxC5Qm+hVQDwhmu1JkiGAIF1Jo2MwYTAdBgNVHQ4EFgQU\n"
+"sbj19vaWoWYfY5IP901oDYN94tcwHwYDVR0jBBgwFoAUsbj19vaWoWYfY5IP901o\n"
+"DYN94tcwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwCwYJYIZIAWUD\n"
+"BAMKA0gAMEUCIQCniTsnEYel6HscrUO7JWs+VnvyqGV5CkRIwgGCN5neQwIgCco6\n"
+"aVh8ZrDsPkjclhFBXF70Qoh9T56f2LdYFvjybdc=\n"
+"-----END CERTIFICATE-----\n";
+
+/* Certificate for intermediary im.unittest.o7s used for signing */
+static const char * intermediate_ca_crt = \
+"-----BEGIN CERTIFICATE-----\n"
+"MIICgzCCAimgAwIBAgICEAAwCwYJYIZIAWUDBAMKMIGQMQswCQYDVQQGEwJCRTEM\n"
+"MAoGA1UECAwDT1ZMMQ4wDAYDVQQHDAVHaGVudDEMMAoGA1UECgwDbzdzMRUwEwYD\n"
+"VQQLDAx1bml0dGVzdC5vN3MxGDAWBgNVBAMMD2NhLnVuaXR0ZXN0Lm83czEkMCIG\n"
+"CSqGSIb3DQEJARYVZHVtbXlAb3Vyb2Jvcm9zLnJvY2tzMB4XDTI1MDYyMjE0MTU0\n"
+"M1oXDTM1MDYyMDE0MTU0M1owWjELMAkGA1UEBhMCQkUxDDAKBgNVBAgMA09WTDEM\n"
+"MAoGA1UECgwDbzdzMRUwEwYDVQQLDAx1bml0dGVzdC5vN3MxGDAWBgNVBAMMD2lt\n"
+"LnVuaXR0ZXN0Lm83czBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABC1/rn6yG22c\n"
+"38lxYGym4VcEZ6+lET5AfcaBsRKpvQj4NwfPG5BCoWwl/rwqKEGmcuwzubiGS1K9\n"
+"hZaxZWp6WfejgaYwgaMwHQYDVR0OBBYEFBfSiMt8k7TKMp2lVsdlunBLGJQhMB8G\n"
+"A1UdIwQYMBaAFLG49fb2lqFmH2OSD/dNaA2DfeLXMBIGA1UdEwEB/wQIMAYBAf8C\n"
+"AQAwDgYDVR0PAQH/BAQDAgGGMBEGA1UdHwQKMAgwBqAEoAKGADAqBggrBgEFBQcB\n"
+"AQQeMBwwDAYIKwYBBQUHMAKGADAMBggrBgEFBQcwAYYAMAsGCWCGSAFlAwQDCgNH\n"
+"ADBEAiBjgMvCgnPz+xy4I1Msb6EwfwdIHr4eHqEfsGQjWf9M8gIgJyy6Bkg6Nkb4\n"
+"uLdf/8CFP5yKKP1H26F8gx1VrGtr+PM=\n"
+"-----END CERTIFICATE-----\n";
+
+/* Server server-1.unittest.o7s private-public key pair */
+static const char * server_ec_pkp = \
+"-----BEGIN EC PRIVATE KEY-----\n"
+"MHcCAQEEIOLEoARQqt9oQkZhdqYrrDltVtcX7TIOYTQqE+GWCIwEoAoGCCqGSM49\n"
+"AwEHoUQDQgAEzHlm1xTYnWncOymJ29ubJ3cHShG67JE+floT7L8ipqRNW4/FUwPN\n"
+"zR/49iM0+A3Nq0ImjzkA6B7E3LvlrwokYQ==\n"
+"-----END EC PRIVATE KEY-----\n";
+
+/* Public key for the Private key */
+static const char * server_ec_pk = \
+"-----BEGIN PUBLIC KEY-----\n"
+"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEzHlm1xTYnWncOymJ29ubJ3cHShG6\n"
+"7JE+floT7L8ipqRNW4/FUwPNzR/49iM0+A3Nq0ImjzkA6B7E3LvlrwokYQ==\n"
+"-----END PUBLIC KEY-----\n";
+
+/* Valid signed server certificate for server-1.unittest.o7s */
+static const char * signed_server_crt = \
+"-----BEGIN CERTIFICATE-----\n"
+"MIIDgzCCAyegAwIBAgICEAAwCwYJYIZIAWUDBAMKMFoxCzAJBgNVBAYTAkJFMQww\n"
+"CgYDVQQIDANPVkwxDDAKBgNVBAoMA283czEVMBMGA1UECwwMdW5pdHRlc3Qubzdz\n"
+"MRgwFgYDVQQDDA9pbS51bml0dGVzdC5vN3MwHhcNMjUwNjIyMTQzODMxWhcNMjcw\n"
+"NjIyMTQzODMxWjBwMQswCQYDVQQGEwJCRTEMMAoGA1UECAwDT1ZMMQ4wDAYDVQQH\n"
+"DAVHaGVudDEMMAoGA1UECgwDbzdzMRUwEwYDVQQLDAx1bml0dGVzdC5vN3MxHjAc\n"
+"BgNVBAMMFXNlcnZlci0xLnVuaXR0ZXN0Lm83czBZMBMGByqGSM49AgEGCCqGSM49\n"
+"AwEHA0IABMx5ZtcU2J1p3Dspidvbmyd3B0oRuuyRPn5aE+y/IqakTVuPxVMDzc0f\n"
+"+PYjNPgNzatCJo85AOgexNy75a8KJGGjggHEMIIBwDAJBgNVHRMEAjAAMBEGCWCG\n"
+"SAGG+EIBAQQEAwIGQDA6BglghkgBhvhCAQ0ELRYrR3JpbGxlZCBDaGVlc2UgR2Vu\n"
+"ZXJhdGVkIFNlcnZlciBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUIKmznLlTbfKaP78E\n"
+"uSNauQ/4Mcwwgb4GA1UdIwSBtjCBs4AUF9KIy3yTtMoynaVWx2W6cEsYlCGhgZak\n"
+"gZMwgZAxCzAJBgNVBAYTAkJFMQwwCgYDVQQIDANPVkwxDjAMBgNVBAcMBUdoZW50\n"
+"MQwwCgYDVQQKDANvN3MxFTATBgNVBAsMDHVuaXR0ZXN0Lm83czEYMBYGA1UEAwwP\n"
+"Y2EudW5pdHRlc3QubzdzMSQwIgYJKoZIhvcNAQkBFhVkdW1teUBvdXJvYm9yb3Mu\n"
+"cm9ja3OCAhAAMA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATAR\n"
+"BgNVHR8ECjAIMAagBKAChgAwKgYIKwYBBQUHAQEEHjAcMAwGCCsGAQUFBzAChgAw\n"
+"DAYIKwYBBQUHMAGGADAgBgNVHREEGTAXghVzZXJ2ZXItMS51bml0dGVzdC5vN3Mw\n"
+"CwYJYIZIAWUDBAMKA0kAMEYCIQDVoRxvr9j4mbX/CpxsQr5HhjxLnjYzI2SVM+0l\n"
+"z2dxVgIhALwq2q6d8WDHPq59trrlNlnYO+kDqDLS3smnS6LOQYiq\n"
+"-----END CERTIFICATE-----\n";
+
+/* Self-signed by server server-1.unittest.o7s using its key */
+static const char * server_crt = \
+"-----BEGIN CERTIFICATE-----\n"
+"MIICNzCCAdygAwIBAgIUaKYySFvp8nmd7LcJjdCyyHrgv0owCwYJYIZIAWUDBAMK\n"
+"MHAxCzAJBgNVBAYTAkJFMQwwCgYDVQQIDANPVkwxDjAMBgNVBAcMBUdoZW50MQww\n"
+"CgYDVQQKDANvN3MxFTATBgNVBAsMDHVuaXR0ZXN0Lm83czEeMBwGA1UEAwwVc2Vy\n"
+"dmVyLTEudW5pdHRlc3QubzdzMB4XDTI1MDYyMjE0NTU1MFoXDTM1MDYyMDE0NTU1\n"
+"MFowcDELMAkGA1UEBhMCQkUxDDAKBgNVBAgMA09WTDEOMAwGA1UEBwwFR2hlbnQx\n"
+"DDAKBgNVBAoMA283czEVMBMGA1UECwwMdW5pdHRlc3QubzdzMR4wHAYDVQQDDBVz\n"
+"ZXJ2ZXItMS51bml0dGVzdC5vN3MwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATM\n"
+"eWbXFNidadw7KYnb25sndwdKEbrskT5+WhPsvyKmpE1bj8VTA83NH/j2IzT4Dc2r\n"
+"QiaPOQDoHsTcu+WvCiRho1MwUTAdBgNVHQ4EFgQUIKmznLlTbfKaP78EuSNauQ/4\n"
+"McwwHwYDVR0jBBgwFoAUIKmznLlTbfKaP78EuSNauQ/4McwwDwYDVR0TAQH/BAUw\n"
+"AwEB/zALBglghkgBZQMEAwoDSAAwRQIhAMrhCV+4QY4Pzcn11qY8AW24xSYE77jN\n"
+"oWkJQKoLEhSdAiBCFzCBItjChcDavsuy++HDo3e6VdpmAh0PlTlQTR6Wog==\n"
+"-----END CERTIFICATE-----\n";
+
+static int test_auth_create_destroy_ctx(void)
+{
+ struct auth_ctx * ctx;
+
+ TEST_START();
+
+ ctx = auth_create_ctx();
+ if (ctx == NULL) {
+ printf("Failed to create auth context.\n");
+ goto fail_create;
+ }
+
+ auth_destroy_ctx(ctx);
+
+ TEST_SUCCESS();
+
+ return TEST_RC_SUCCESS;
+ fail_create:
+ TEST_FAIL();
+ return TEST_RC_FAIL;
+}
+
+static int test_load_free_crt(void)
+{
+ void * crt;
+
+ TEST_START();
+
+ if (crypt_load_crt_str(root_ca_crt, &crt) < 0) {
+ printf("Failed to load certificate string.\n");
+ goto fail_load;
+ }
+
+ crypt_free_crt(crt);
+
+ TEST_SUCCESS();
+
+ return TEST_RC_SUCCESS;
+ fail_load:
+ TEST_FAIL();
+ return TEST_RC_FAIL;
+}
+
+static int test_crypt_get_pubkey_crt(void)
+{
+ void * pk;
+ void * crt;
+
+ TEST_START();
+
+ if (crypt_load_crt_str(signed_server_crt, &crt) < 0) {
+ printf("Failed to load server certificate from string.\n");
+ goto fail_load;
+ }
+
+ if (crypt_get_pubkey_crt(crt, &pk) < 0) {
+ printf("Failed to get public key from certificate.\n");
+ goto fail_get_pubkey;
+ }
+
+ crypt_free_key(pk);
+ crypt_free_crt(crt);
+
+ TEST_SUCCESS();
+
+ return TEST_RC_SUCCESS;
+
+ fail_get_pubkey:
+ crypt_free_crt(crt);
+ fail_load:
+ TEST_FAIL();
+ return TEST_RC_FAIL;
+}
+
+static int test_check_crt_name(void)
+{
+ void * crt;
+
+ TEST_START();
+
+ if (crypt_load_crt_str(signed_server_crt, &crt) < 0) {
+ printf("Failed to load certificate from string.\n");
+ goto fail_load;
+ }
+
+ if (crypt_check_crt_name(crt, "server-1.unittest.o7s") < 0) {
+ printf("Failed to verify correct name.\n");
+ goto fail_check;
+ }
+
+ if (crypt_check_crt_name(crt, "bogus.name") == 0) {
+ printf("Failed to detect incorrect name.\n");
+ goto fail_check;
+ }
+
+ crypt_free_crt(crt);
+
+ TEST_SUCCESS();
+
+ return TEST_RC_SUCCESS;
+ fail_check:
+ crypt_free_crt(crt);
+ fail_load:
+ TEST_FAIL();
+ return TEST_RC_FAIL;
+}
+
+static int test_load_free_privkey(void)
+{
+ void * key;
+
+ TEST_START();
+
+ if (crypt_load_privkey_str(server_ec_pkp, &key) < 0) {
+ printf("Failed to load server key pair from string.\n");
+ goto fail_load;
+ }
+
+ crypt_free_key(key);
+
+ TEST_SUCCESS();
+
+ return TEST_RC_SUCCESS;
+ fail_load:
+ TEST_FAIL();
+ return TEST_RC_FAIL;
+}
+
+static int test_load_free_pubkey(void)
+{
+ void * key;
+
+ TEST_START();
+
+ if (crypt_load_pubkey_str(server_ec_pk, &key) < 0) {
+ printf("Failed to load server public key from string.\n");
+ goto fail_load;
+ }
+
+ crypt_free_key(key);
+
+ TEST_SUCCESS();
+
+ return TEST_RC_SUCCESS;
+ fail_load:
+ TEST_FAIL();
+ return TEST_RC_FAIL;
+}
+
+static int test_crypt_check_pubkey_crt(void)
+{
+ void * pk;
+ void * crt_pk;
+ void * crt;
+
+ TEST_START();
+
+ if (crypt_load_crt_str(signed_server_crt, &crt) < 0) {
+ printf("Failed to load public certificate from string.\n");
+ goto fail_crt;
+ }
+
+ if (crypt_load_pubkey_str(server_ec_pk, &pk) < 0) {
+ printf("Failed to load public key from string.\n");
+ goto fail_pubkey;
+ }
+
+ if (crypt_get_pubkey_crt(crt, &crt_pk) < 0) {
+ printf("Failed to get public key from certificate.\n");
+ goto fail_get_pubkey;
+ }
+
+ if (crypt_cmp_key(pk, crt_pk) != 0) {
+ printf("Public keys do not match .\n");
+ goto fail_check;
+ }
+
+
+ crypt_free_key(crt_pk);
+ crypt_free_key(pk);
+ crypt_free_crt(crt);
+
+ TEST_SUCCESS();
+
+ return TEST_RC_SUCCESS;
+ fail_check:
+ crypt_free_key(crt_pk);
+ fail_get_pubkey:
+ crypt_free_key(pk);
+ fail_pubkey:
+ crypt_free_crt(crt);
+ fail_crt:
+ TEST_FAIL();
+ return TEST_RC_FAIL;
+}
+
+static int test_verify_crt(void)
+{
+ struct auth_ctx * auth;
+ void * _server_crt;
+ void * _signed_server_crt;
+ void * _root_ca_crt;
+ void * _intermediate_ca_crt;
+
+ TEST_START();
+
+
+ auth = auth_create_ctx();
+ if (auth == NULL) {
+ printf("Failed to create auth context.\n");
+ goto fail_create_ctx;
+ }
+
+ if (crypt_load_crt_str(server_crt, &_server_crt) < 0) {
+ printf("Failed to load self-signed crt from string.\n");
+ goto fail_load_server_crt;
+ }
+
+ if (crypt_load_crt_str(signed_server_crt, &_signed_server_crt) < 0) {
+ printf("Failed to load signed crt from string.\n");
+ goto fail_load_signed_server_crt;
+ }
+
+ if (crypt_load_crt_str(root_ca_crt, &_root_ca_crt) < 0) {
+ printf("Failed to load root crt from string.\n");
+ goto fail_load_root_ca_crt;
+ }
+
+ if (crypt_load_crt_str(intermediate_ca_crt, &_intermediate_ca_crt) < 0) {
+ printf("Failed to load intermediate crt from string.\n");
+ goto fail_load_intermediate_ca_crt;
+ }
+
+ if (auth_add_crt_to_store(auth, _root_ca_crt) < 0) {
+ printf("Failed to add root ca crt to auth store.\n");
+ goto fail_verify;
+ }
+
+ if (auth_add_crt_to_store(auth, _intermediate_ca_crt) < 0) {
+ printf("Failed to add intermediate ca crt to auth store.\n");
+ goto fail_verify;
+ }
+
+ if (auth_verify_crt(auth, _signed_server_crt) < 0) {
+ printf("Failed to verify signed crt with ca crt.\n");
+ goto fail_verify;
+ }
+
+ if (auth_verify_crt(auth, _server_crt) == 0) {
+ printf("Failed to detect untrusted crt.\n");
+ goto fail_verify;
+ }
+
+ crypt_free_crt(_intermediate_ca_crt);
+ crypt_free_crt(_root_ca_crt);
+ crypt_free_crt(_signed_server_crt);
+ crypt_free_crt(_server_crt);
+
+ auth_destroy_ctx(auth);
+
+ TEST_SUCCESS();
+
+ return TEST_RC_SUCCESS;
+ fail_verify:
+ crypt_free_crt(_intermediate_ca_crt);
+ fail_load_intermediate_ca_crt:
+ crypt_free_crt(_root_ca_crt);
+ fail_load_root_ca_crt:
+ crypt_free_crt(_signed_server_crt);
+ fail_load_signed_server_crt:
+ crypt_free_crt(_server_crt);
+ fail_load_server_crt:
+ auth_destroy_ctx(auth);
+ fail_create_ctx:
+ TEST_FAIL();
+ return TEST_RC_FAIL;
+}
+
+int test_auth_sign(void)
+{
+ uint8_t buf[TEST_MSG_SIZE];
+ void * pkp;
+ void * pk;
+ buffer_t msg;
+ buffer_t sig;
+
+ TEST_START();
+
+ msg.data = buf;
+ msg.len = sizeof(buf);
+
+ if (random_buffer(msg.data, msg.len) < 0) {
+ printf("Failed to generate random message.\n");
+ goto fail_init;
+ }
+
+ if (crypt_load_privkey_str(server_ec_pkp, &pkp) < 0) {
+ printf("Failed to load server key pair from string.\n");
+ goto fail_init;
+ }
+
+ if (crypt_load_pubkey_str(server_ec_pk, &pk) < 0) {
+ printf("Failed to load public key.\n");
+ goto fail_pubkey;
+ }
+
+ if (auth_sign(pkp, msg, &sig) < 0) {
+ printf("Failed to sign message.\n");
+ goto fail_sign;
+ }
+
+ if (auth_verify_sig(pk, msg, sig) < 0) {
+ printf("Failed to verify signature.\n");
+ goto fail_verify;
+ }
+
+ freebuf(sig);
+
+ crypt_free_key(pk);
+ crypt_free_key(pkp);
+
+ TEST_SUCCESS();
+
+ return TEST_RC_SUCCESS;
+ fail_verify:
+ freebuf(sig);
+ fail_sign:
+ crypt_free_key(pk);
+ fail_pubkey:
+ crypt_free_key(pkp);
+ fail_init:
+ return TEST_RC_FAIL;
+}
+
+int test_auth_bad_signature(void)
+{
+ uint8_t buf[TEST_MSG_SIZE];
+ void * pkp;
+ void * pk;
+ buffer_t msg;
+ buffer_t sig;
+ buffer_t fake_sig;
+
+ TEST_START();
+
+ msg.data = buf;
+ msg.len = sizeof(buf);
+
+ if (random_buffer(msg.data, msg.len) < 0) {
+ printf("Failed to generate random message.\n");
+ goto fail_init;
+ }
+
+ if (crypt_load_privkey_str(server_ec_pkp, &pkp) < 0) {
+ printf("Failed to load server key pair from string.\n");
+ goto fail_init;
+ }
+
+ if (crypt_load_pubkey_str(server_ec_pk, &pk) < 0) {
+ printf("Failed to load public key.\n");
+ goto fail_pubkey;
+ }
+
+ if (auth_sign(pkp, msg, &sig) < 0) {
+ printf("Failed to sign message.\n");
+ goto fail_sign;
+ }
+
+ fake_sig.data = malloc(sig.len);
+ if (fake_sig.data == NULL) {
+ printf("Failed to allocate memory for fake signature.\n");
+ goto fail_malloc;
+ }
+
+ fake_sig.len = sig.len;
+ if (random_buffer(fake_sig.data, fake_sig.len) < 0) {
+ printf("Failed to generate random fake signature.\n");
+ goto fail_malloc;
+ }
+
+ if (auth_verify_sig(pk, msg, fake_sig) == 0) {
+ printf("Failed to detect bad signature.\n");
+ goto fail_verify;
+ }
+
+ freebuf(sig);
+
+ crypt_free_key(pk);
+ crypt_free_key(pkp);
+
+ TEST_SUCCESS();
+
+ return TEST_RC_SUCCESS;
+ fail_verify:
+ freebuf(fake_sig);
+ fail_malloc:
+ freebuf(sig);
+ fail_sign:
+ crypt_free_key(pk);
+ fail_pubkey:
+ crypt_free_key(pkp);
+ fail_init:
+ return TEST_RC_FAIL;
+}
+
+int auth_test(int argc,
+ char ** argv)
+{
+ int ret = 0;
+
+ (void) argc;
+ (void) argv;
+
+ ret |= test_auth_create_destroy_ctx();
+#ifdef HAVE_OPENSSL
+ ret |= test_load_free_crt();
+ ret |= test_check_crt_name();
+ ret |= test_crypt_get_pubkey_crt();
+ ret |= test_load_free_privkey();
+ ret |= test_load_free_pubkey();
+ ret |= test_crypt_check_pubkey_crt();
+ ret |= test_verify_crt();
+ ret |= test_auth_sign();
+ ret |= test_auth_bad_signature();
+#else
+ (void) test_load_free_crt;
+ (void) test_check_crt_name;
+ (void) test_crypt_get_pubkey_crt;
+ (void) test_load_free_privkey;
+ (void) test_load_free_pubkey;
+ (void) test_crypt_check_pubkey_crt;
+ (void) test_verify_crt;
+ (void) test_auth_sign;
+ (void) test_auth_bad_signature;
+
+ ret = TEST_RC_SKIP;
+#endif
+ return ret;
+}
diff --git a/src/lib/tests/crypt_test.c b/src/lib/tests/crypt_test.c
new file mode 100644
index 00000000..7f011e5c
--- /dev/null
+++ b/src/lib/tests/crypt_test.c
@@ -0,0 +1,256 @@
+/*
+ * Ouroboros - Copyright (C) 2016 - 2024
+ *
+ * Test of the cryptography functions
+ *
+ * Dimitri Staessens <dimitri@ouroboros.rocks>
+ * Sander Vrijders <sander@ouroboros.rocks>
+ *
+ * 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., http://www.fsf.org/about/contact/.
+ */
+
+#include "config.h"
+
+#include <ouroboros/test.h>
+#include <ouroboros/crypt.h>
+#include <ouroboros/random.h>
+#include <ouroboros/utils.h>
+
+#define TEST_PACKET_SIZE 1500
+
+static int test_crypt_create_destroy(void)
+{
+ struct crypt_ctx * ctx;
+
+ TEST_START();
+
+ ctx = crypt_create_ctx(0, NULL);
+ if (ctx == NULL) {
+ printf("Failed to initialize cryptography.\n");
+ goto fail;
+ }
+
+ crypt_destroy_ctx(ctx);
+
+ TEST_SUCCESS();
+
+ return TEST_RC_SUCCESS;
+ fail:
+ TEST_FAIL();
+ return TEST_RC_FAIL;
+}
+
+static int test_crypt_create_destroy_with_key(void)
+{
+ struct crypt_ctx * ctx;
+ uint8_t key[SYMMKEYSZ];
+
+ TEST_START();
+
+ memset(key, 0, sizeof(key));
+
+ ctx = crypt_create_ctx(1, key);
+ if (ctx == NULL) {
+ printf("Failed to initialize cryptography.\n");
+ goto fail;
+ }
+
+ crypt_destroy_ctx(ctx);
+
+ TEST_SUCCESS();
+
+ return TEST_RC_SUCCESS;
+ fail:
+ TEST_FAIL();
+ return TEST_RC_FAIL;
+}
+
+static int test_crypt_dh_pkp_create_destroy(void)
+{
+ void * pkp;
+ uint8_t buf[MSGBUFSZ];
+
+ TEST_START();
+
+ if (crypt_dh_pkp_create(&pkp, buf) < 0) {
+ printf("Failed to create DH PKP.");
+ goto fail;
+ }
+
+ crypt_dh_pkp_destroy(pkp);
+
+ TEST_SUCCESS();
+
+ return TEST_RC_SUCCESS;
+ fail:
+ TEST_FAIL();
+ return TEST_RC_FAIL;
+}
+
+static int test_crypt_dh_derive(void)
+{
+ void * pkp1;
+ void * pkp2;
+ buffer_t pk1;
+ buffer_t pk2;
+ ssize_t len;
+ uint8_t buf1[MSGBUFSZ];
+ uint8_t buf2[MSGBUFSZ];
+ uint8_t s1[SYMMKEYSZ];
+ uint8_t s2[SYMMKEYSZ];
+
+ TEST_START();
+
+ len = crypt_dh_pkp_create(&pkp1, buf1);
+ if (len < 0) {
+ printf("Failed to create first key pair.");
+ goto fail_pkp1;
+ }
+
+ pk1.len = (size_t) len;
+ pk1.data = buf1;
+
+ len = crypt_dh_pkp_create(&pkp2, buf2);
+ if (len < 0) {
+ printf("Failed to create second key pair.");
+ goto fail_pkp2;
+ }
+
+ pk2.len = (size_t) len;
+ pk2.data = buf2;
+
+ if (crypt_dh_derive(pkp1, pk2, s1) < 0) {
+ printf("Failed to derive first key.");
+ goto fail;
+ }
+
+ if (crypt_dh_derive(pkp2, pk1, s2) < 0) {
+ printf("Failed to derive second key.");
+ goto fail;
+ }
+
+ if (memcmp(s1, s2, SYMMKEYSZ) != 0) {
+ printf("Derived keys do not match.");
+ goto fail;
+ }
+
+ crypt_dh_pkp_destroy(pkp2);
+ crypt_dh_pkp_destroy(pkp1);
+
+ TEST_SUCCESS();
+
+ return TEST_RC_SUCCESS;
+ fail:
+ crypt_dh_pkp_destroy(pkp2);
+ fail_pkp2:
+ crypt_dh_pkp_destroy(pkp1);
+ fail_pkp1:
+ TEST_FAIL();
+ return TEST_RC_FAIL;
+}
+
+int test_crypt_encrypt_decrypt(void)
+{
+ uint8_t pkt[TEST_PACKET_SIZE];
+ uint8_t key[SYMMKEYSZ];
+ struct crypt_ctx * ctx;
+ buffer_t in;
+ buffer_t out;
+ buffer_t out2;
+
+ TEST_START();
+
+ if (random_buffer(key, sizeof(key)) < 0) {
+ printf("Failed to generate random key.\n");
+ goto fail_init;
+ }
+
+ if (random_buffer(pkt, sizeof(pkt)) < 0) {
+ printf("Failed to generate random data.\n");
+ goto fail_init;
+ }
+
+ ctx = crypt_create_ctx(1, key);
+ if (ctx == NULL) {
+ printf("Failed to initialize cryptography.\n");
+ goto fail_init;
+ }
+
+ in.len = sizeof(pkt);
+ in.data = pkt;
+
+ if (crypt_encrypt(ctx, in, &out) < 0) {
+ printf("Encryption failed.\n");
+ goto fail_encrypt;
+ }
+
+ if (out.len < in.len) {
+ printf("Encryption returned too little data.\n");
+ goto fail_encrypt;
+ }
+
+ if (crypt_decrypt(ctx, out, &out2) < 0) {
+ printf("Decryption failed.\n");
+ goto fail_decrypt;
+ }
+
+ if (out2.len != in.len) {
+ printf("Decrypted data length does not match original.\n");
+ goto fail_chk;
+ }
+
+ if (memcmp(in.data, out2.data, in.len) != 0) {
+ printf("Decrypted data does not match original.\n");
+ goto fail_chk;
+ }
+
+ crypt_destroy_ctx(ctx);
+
+ TEST_SUCCESS();
+
+ return TEST_RC_SUCCESS;
+ fail_chk:
+ freebuf(out2);
+ fail_decrypt:
+ freebuf(out);
+ fail_encrypt:
+ crypt_destroy_ctx(ctx);
+ fail_init:
+ TEST_FAIL();
+ return TEST_RC_FAIL;
+}
+
+int crypt_test(int argc,
+ char ** argv)
+{
+ int ret = 0;
+
+ (void) argc;
+ (void) argv;
+
+ ret |= test_crypt_create_destroy();
+ ret |= test_crypt_create_destroy_with_key();
+#ifdef HAVE_OPENSSL
+ ret |= test_crypt_dh_pkp_create_destroy();
+ ret |= test_crypt_dh_derive();
+ ret |= test_crypt_encrypt_decrypt();
+#else
+ (void) test_crypt_dh_pkp_create_destroy;
+ (void) test_crypt_dh_derive;
+ (void) test_crypt_encrypt_decrypt;
+
+ ret = TEST_RC_SKIP;
+#endif
+ return ret;
+}
diff --git a/src/lib/tests/sockets_test.c b/src/lib/tests/sockets_test.c
new file mode 100644
index 00000000..bbf2323b
--- /dev/null
+++ b/src/lib/tests/sockets_test.c
@@ -0,0 +1,98 @@
+/*
+ * Ouroboros - Copyright (C) 2016 - 2024
+ *
+ * Tests for socket.c
+ *
+ * Dimitri Staessens <dimitri@ouroboros.rocks>
+ * Sander Vrijders <sander@ouroboros.rocks>
+ *
+ * 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., http://www.fsf.org/about/contact/.
+ */
+
+#define _POSIX_C_SOURCE 200112L
+
+#include <ouroboros/sockets.h>
+#include <ouroboros/test.h>
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#define TEST_PID 1234
+#define TEST_PID_STR "1234"
+#define TEST_SERVER_PATH "/tmp/test.sock"
+#define TEST_SERVER_PREFIX "/tmp/ouroboros/test."
+#define TEST_SOCK_PATH_PREFIX "var/run/ouroboros/test."
+
+static int test_sock_path(void)
+{
+ char * path;
+ char * exp = TEST_SOCK_PATH_PREFIX TEST_PID_STR SOCK_PATH_SUFFIX;
+
+ TEST_START();
+
+ path = sock_path(TEST_PID, TEST_SOCK_PATH_PREFIX);
+ if (path == NULL) {
+ printf("Path is NULL.\n");
+ goto fail_path;
+ }
+
+ if (strcmp(path, exp) != 0) {
+ printf("Expected path '%s', got '%s'.\n", exp, path);
+ goto fail_cmp;
+ }
+
+ free(path);
+
+ TEST_SUCCESS();
+ return TEST_RC_SUCCESS;
+ fail_cmp:
+ free(path);
+ fail_path:
+ TEST_FAIL();
+ return TEST_RC_FAIL;
+}
+
+static int test_server_socket_open(void)
+{
+ int sockfd;
+
+ TEST_START();
+
+ sockfd = server_socket_open(TEST_SERVER_PATH);
+ if (sockfd < 0) {
+ printf("Failed to open server socket.\n");
+ goto fail_sock;
+ }
+
+ close(sockfd);
+
+ unlink(TEST_SERVER_PATH);
+
+ TEST_SUCCESS();
+ return TEST_RC_SUCCESS;
+ fail_sock:
+ TEST_FAIL();
+ return TEST_RC_FAIL;
+}
+
+int sockets_test(void)
+{
+ int ret = 0;
+
+ ret |= test_sock_path();
+ ret |= test_server_socket_open();
+
+ return ret;
+}
diff --git a/src/lib/tests/time_test.c b/src/lib/tests/time_test.c
index 65f896bb..77fecdac 100644
--- a/src/lib/tests/time_test.c
+++ b/src/lib/tests/time_test.c
@@ -28,12 +28,14 @@
static void ts_print(struct timespec * s)
{
- printf("timespec is %zd:%ld.\n", (ssize_t) s->tv_sec, s->tv_nsec);
+ printf("timespec is %zd:%ld.\n",
+ (ssize_t) s->tv_sec, s->tv_nsec);
}
static void tv_print(struct timeval * v)
{
- printf("timeval is %zd:%zu.\n", (ssize_t) v->tv_sec, (size_t) v->tv_usec);
+ printf("timeval is %zd:%zu.\n",
+ (ssize_t) v->tv_sec, (size_t) v->tv_usec);
}
static void ts_init(struct timespec * s,
diff --git a/src/lib/tests/tpm_test.c b/src/lib/tests/tpm_test.c
new file mode 100644
index 00000000..98d4fab3
--- /dev/null
+++ b/src/lib/tests/tpm_test.c
@@ -0,0 +1,104 @@
+/*
+ * Ouroboros - Copyright (C) 2016 - 2024
+ *
+ * Tests for the threadpool manager
+ *
+ * Dimitri Staessens <dimitri@ouroboros.rocks>
+ * Sander Vrijders <sander@ouroboros.rocks>
+ *
+ * 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., http://www.fsf.org/about/contact/.
+ */
+
+
+#include "tpm.c"
+
+#include <ouroboros/test.h>
+
+static void * test_func(void * o)
+{
+ (void) o;
+
+ while(1)
+ sleep(1);
+
+ return NULL;
+}
+
+static int test_tpm_create_destroy(void)
+{
+ struct tpm *tpm;
+
+ TEST_START();
+
+ tpm = tpm_create(2, 2, &test_func, NULL);
+ if (tpm == NULL) {
+ printf("Failed to initialize TPM.\n");
+ goto fail;
+ }
+
+ tpm_destroy(tpm);
+
+ TEST_SUCCESS();
+
+ return TEST_RC_SUCCESS;
+ fail:
+ TEST_FAIL();
+ return TEST_RC_FAIL;
+}
+
+static int test_tpm_start_stop(void * (* fn)(void *),
+ void * o)
+{
+ struct tpm *tpm;
+
+ TEST_START();
+
+ tpm = tpm_create(2, 2, fn, o);
+ if (tpm == NULL) {
+ printf("Failed to initialize TPM.\n");
+ goto fail_create;
+ }
+
+ if (tpm_start(tpm) < 0) {
+ printf("Failed to start TPM.\n");
+ goto fail_start;
+ }
+
+ tpm_stop(tpm);
+
+ tpm_destroy(tpm);
+
+ TEST_SUCCESS();
+
+ return TEST_RC_SUCCESS;
+ fail_start:
+ tpm_destroy(tpm);
+ fail_create:
+ TEST_FAIL();
+ return TEST_RC_FAIL;
+}
+
+int tpm_test(int argc,
+ char ** argv)
+{
+ int ret = 0;
+
+ (void) argc;
+ (void) argv;
+
+ ret |= test_tpm_create_destroy();
+ ret |= test_tpm_start_stop(&test_func, NULL);
+
+ return ret;
+}