diff options
Diffstat (limited to 'src/lib/tests')
-rw-r--r-- | src/lib/tests/CMakeLists.txt | 16 | ||||
-rw-r--r-- | src/lib/tests/auth_test.c | 570 | ||||
-rw-r--r-- | src/lib/tests/bitmap_test.c | 27 | ||||
-rw-r--r-- | src/lib/tests/btree_test.c | 2 | ||||
-rw-r--r-- | src/lib/tests/crc32_test.c | 2 | ||||
-rw-r--r-- | src/lib/tests/crypt_test.c | 256 | ||||
-rw-r--r-- | src/lib/tests/hash_test.c | 202 | ||||
-rw-r--r-- | src/lib/tests/md5_test.c | 2 | ||||
-rw-r--r-- | src/lib/tests/sha3_test.c | 2 | ||||
-rw-r--r-- | src/lib/tests/shm_rbuff_test.c | 2 | ||||
-rw-r--r-- | src/lib/tests/sockets_test.c | 98 | ||||
-rw-r--r-- | src/lib/tests/time_test.c (renamed from src/lib/tests/time_utils_test.c) | 14 | ||||
-rw-r--r-- | src/lib/tests/tpm_test.c | 104 |
13 files changed, 1271 insertions, 26 deletions
diff --git a/src/lib/tests/CMakeLists.txt b/src/lib/tests/CMakeLists.txt index 9e23b0ee..2791dd0d 100644 --- a/src/lib/tests/CMakeLists.txt +++ b/src/lib/tests/CMakeLists.txt @@ -3,13 +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 - time_utils_test.c + sockets_test.c + time_test.c + tpm_test.c ) add_executable(${PARENT_DIR}_test EXCLUDE_FROM_ALL ${${PARENT_DIR}_tests}) @@ -19,9 +24,16 @@ target_link_libraries(${PARENT_DIR}_test ouroboros-common) add_dependencies(check ${PARENT_DIR}_test) set(tests_to_run ${${PARENT_DIR}_tests}) -remove(tests_to_run test_suite.c) +if(CMAKE_VERSION VERSION_LESS "3.29.0") + remove(tests_to_run test_suite.c) +else () + list(POP_FRONT tests_to_run) +endif() 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..c3d42b8f --- /dev/null +++ b/src/lib/tests/auth_test.c @@ -0,0 +1,570 @@ +/* + * 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" +"MIICiTCCAi+gAwIBAgIUe4iFIymeUTgutBrdvcxFihOVHnowCgYIKoZIzj0EAwIw\n" +"gZExCzAJBgNVBAYTAkJFMQwwCgYDVQQIDANPVkwxDjAMBgNVBAcMBUdoZW50MQww\n" +"CgYDVQQKDANvN3MxFTATBgNVBAsMDHVuaXR0ZXN0Lm83czEZMBcGA1UEAwwQY2Ey\n" +"LnVuaXR0ZXN0Lm83czEkMCIGCSqGSIb3DQEJARYVZHVtbXlAb3Vyb2Jvcm9zLnJv\n" +"Y2tzMB4XDTI1MDcwNDEyMDUwOVoXDTI1MDgwMzEyMDUwOVowgZExCzAJBgNVBAYT\n" +"AkJFMQwwCgYDVQQIDANPVkwxDjAMBgNVBAcMBUdoZW50MQwwCgYDVQQKDANvN3Mx\n" +"FTATBgNVBAsMDHVuaXR0ZXN0Lm83czEZMBcGA1UEAwwQY2EyLnVuaXR0ZXN0Lm83\n" +"czEkMCIGCSqGSIb3DQEJARYVZHVtbXlAb3Vyb2Jvcm9zLnJvY2tzMFkwEwYHKoZI\n" +"zj0CAQYIKoZIzj0DAQcDQgAE7L882J12ELmVTAO3JBhG/CiEsh4VwgZnP5FXEcgI\n" +"3oVavhep7lhBCVcv8zcjHcQuUJvoVUA8IZrtSZIhgCBdSaNjMGEwHQYDVR0OBBYE\n" +"FLG49fb2lqFmH2OSD/dNaA2DfeLXMB8GA1UdIwQYMBaAFLG49fb2lqFmH2OSD/dN\n" +"aA2DfeLXMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49\n" +"BAMCA0gAMEUCIQCHLdjzuop33phYcxTMs12pQcRk9GDbiKd1VZr6/SxutAIgBU1/\n" +"JSTSWB29kFFiM9ZdMV7M/tiZH9nSz1M8XhsTIGk=\n" +"-----END CERTIFICATE-----\n"; + +/* Certificate for intermediary im.unittest.o7s used for signing */ +static const char * intermediate_ca_crt = \ +"-----BEGIN CERTIFICATE-----\n" +"MIIChTCCAiqgAwIBAgICEAIwCgYIKoZIzj0EAwIwgZExCzAJBgNVBAYTAkJFMQww\n" +"CgYDVQQIDANPVkwxDjAMBgNVBAcMBUdoZW50MQwwCgYDVQQKDANvN3MxFTATBgNV\n" +"BAsMDHVuaXR0ZXN0Lm83czEZMBcGA1UEAwwQY2EyLnVuaXR0ZXN0Lm83czEkMCIG\n" +"CSqGSIb3DQEJARYVZHVtbXlAb3Vyb2Jvcm9zLnJvY2tzMB4XDTI1MDcwNDEzMTc1\n" +"N1oXDTM1MDcwMjEzMTc1N1owWzELMAkGA1UEBhMCQkUxDDAKBgNVBAgMA09WTDEM\n" +"MAoGA1UECgwDbzdzMRUwEwYDVQQLDAx1bml0dGVzdC5vN3MxGTAXBgNVBAMMEGlt\n" +"Mi51bml0dGVzdC5vN3MwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQXhtgyz2ot\n" +"xWMC5PW3lchYyzYLIU0VsI4aAALjRcRoq3ZunC1cvBWv34fkSrwBCCsQvLIBP+8j\n" +"qgi5j2kve8QIo4GmMIGjMB0GA1UdDgQWBBQV95lHHxBZYpCvsDDzOMO7ayG9xDAf\n" +"BgNVHSMEGDAWgBSxuPX29pahZh9jkg/3TWgNg33i1zASBgNVHRMBAf8ECDAGAQH/\n" +"AgEAMA4GA1UdDwEB/wQEAwIBhjARBgNVHR8ECjAIMAagBKAChgAwKgYIKwYBBQUH\n" +"AQEEHjAcMAwGCCsGAQUFBzAChgAwDAYIKwYBBQUHMAGGADAKBggqhkjOPQQDAgNJ\n" +"ADBGAiEAlw7Q08qDZ/OftfTPdoTvNezDW/1ChQQcwsmQxcbBTfsCIQDWCaB+PHVo\n" +"NnkLn+73oMj8w4pXGLNKAkX0z7yPJ4QhwA==\n" +"-----END CERTIFICATE-----\n"; + +/* Server server-1.unittest.o7s private-public key pair */ +static const char * server_ec_pkp = \ +"-----BEGIN EC PRIVATE KEY-----\n" +"MHcCAQEEIC13y+5jdKe80HBJD7WITpQamcn3rrkTX1r0v+JwSk4NoAoGCCqGSM49\n" +"AwEHoUQDQgAEcC0yLAfUtufH8cdLybrdWPc6U+xRuhDhqqrEcBO5+eob2xyqEaNk\n" +"nIV/86724zPptGRahWz0rzW2PvNppJdNBg==\n" +"-----END EC PRIVATE KEY-----\n"; + +/* Public key for the Private key */ +static const char * server_ec_pk = \ +"-----BEGIN PUBLIC KEY-----\n" +"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEcC0yLAfUtufH8cdLybrdWPc6U+xR\n" +"uhDhqqrEcBO5+eob2xyqEaNknIV/86724zPptGRahWz0rzW2PvNppJdNBg==\n" +"-----END PUBLIC KEY-----\n"; + +/* Valid signed server certificate for server-1.unittest.o7s, SHA2 */ +static const char * signed_server_crt = \ +"-----BEGIN CERTIFICATE-----\n" +"MIIDgjCCAyigAwIBAgICEAIwCgYIKoZIzj0EAwIwWzELMAkGA1UEBhMCQkUxDDAK\n" +"BgNVBAgMA09WTDEMMAoGA1UECgwDbzdzMRUwEwYDVQQLDAx1bml0dGVzdC5vN3Mx\n" +"GTAXBgNVBAMMEGltMi51bml0dGVzdC5vN3MwHhcNMjUwNzA0MTMxODI5WhcNMzUw\n" +"NzAyMTMxODI5WjBwMQswCQYDVQQGEwJCRTEMMAoGA1UECAwDT1ZMMQ4wDAYDVQQH\n" +"DAVHaGVudDEMMAoGA1UECgwDbzdzMRUwEwYDVQQLDAx1bml0dGVzdC5vN3MxHjAc\n" +"BgNVBAMMFXNlcnZlci0yLnVuaXR0ZXN0Lm83czBZMBMGByqGSM49AgEGCCqGSM49\n" +"AwEHA0IABHAtMiwH1Lbnx/HHS8m63Vj3OlPsUboQ4aqqxHATufnqG9scqhGjZJyF\n" +"f/Ou9uMz6bRkWoVs9K81tj7zaaSXTQajggHFMIIBwTAJBgNVHRMEAjAAMBEGCWCG\n" +"SAGG+EIBAQQEAwIGQDA6BglghkgBhvhCAQ0ELRYrR3JpbGxlZCBDaGVlc2UgR2Vu\n" +"ZXJhdGVkIFNlcnZlciBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUTt3xHTwE9amoglxh\n" +"cEMqWv+PpDMwgb8GA1UdIwSBtzCBtIAUFfeZRx8QWWKQr7Aw8zjDu2shvcShgZek\n" +"gZQwgZExCzAJBgNVBAYTAkJFMQwwCgYDVQQIDANPVkwxDjAMBgNVBAcMBUdoZW50\n" +"MQwwCgYDVQQKDANvN3MxFTATBgNVBAsMDHVuaXR0ZXN0Lm83czEZMBcGA1UEAwwQ\n" +"Y2EyLnVuaXR0ZXN0Lm83czEkMCIGCSqGSIb3DQEJARYVZHVtbXlAb3Vyb2Jvcm9z\n" +"LnJvY2tzggIQAjAOBgNVHQ8BAf8EBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwEw\n" +"EQYDVR0fBAowCDAGoASgAoYAMCoGCCsGAQUFBwEBBB4wHDAMBggrBgEFBQcwAoYA\n" +"MAwGCCsGAQUFBzABhgAwIAYDVR0RBBkwF4IVc2VydmVyLTEudW5pdHRlc3Qubzdz\n" +"MAoGCCqGSM49BAMCA0gAMEUCIQDHuDb62w/Uah4nKwUFoJVkr4rgdNGh2Rn3SWaK\n" +"0FV/gAIgOLKorTwSgrTFdyOUkuPOhRs8BEMpah+dp8UTO8AnLvY=\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-2.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/bitmap_test.c b/src/lib/tests/bitmap_test.c index 0815ecff..4dbd6653 100644 --- a/src/lib/tests/bitmap_test.c +++ b/src/lib/tests/bitmap_test.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Test of the bitmap * @@ -27,7 +27,8 @@ #define BITMAP_SIZE 200 -int bitmap_test(int argc, char ** argv) +int bitmap_test(int argc, + char ** argv) { struct bmp * bmp; ssize_t bits = BITMAP_SIZE; @@ -60,27 +61,23 @@ int bitmap_test(int argc, char ** argv) if (!bmp_is_id_valid(bmp, id)) { if (i < BITMAP_SIZE + offset) { printf("Failed valid ID %d (%zd).\n", i, id); - bmp_destroy(bmp); - return -1; + goto fail; } if (id >= offset && id < bits + offset) { printf("Valid ID %zd returned invalid.\n", id); - bmp_destroy(bmp); - return -1; + goto fail; } continue; } if (!bmp_is_id_used(bmp, id)) { printf("ID not marked in use.\n"); - bmp_destroy(bmp); - return -1; + goto fail; } if (id != i) { printf("Wrong ID returned.\n"); - bmp_destroy(bmp); - return -1; + goto fail; } } @@ -89,20 +86,24 @@ int bitmap_test(int argc, char ** argv) if (bmp_release(bmp, r)) { printf("Failed to release ID.\n"); - return -1; + goto fail; } id = bmp_allocate(bmp); if (!bmp_is_id_valid(bmp, id)) continue; + if (id != r) { printf("Wrong prev ID returned.\n"); - bmp_destroy(bmp); - return -1; + goto fail; } } bmp_destroy(bmp); return 0; + + fail: + bmp_destroy(bmp); + return -1; } diff --git a/src/lib/tests/btree_test.c b/src/lib/tests/btree_test.c index 9dc59d32..8bd30370 100644 --- a/src/lib/tests/btree_test.c +++ b/src/lib/tests/btree_test.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Test of the B-tree implementation * diff --git a/src/lib/tests/crc32_test.c b/src/lib/tests/crc32_test.c index a0f70423..a26c8220 100644 --- a/src/lib/tests/crc32_test.c +++ b/src/lib/tests/crc32_test.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Test of the CRC32 function * 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/hash_test.c b/src/lib/tests/hash_test.c new file mode 100644 index 00000000..970d9185 --- /dev/null +++ b/src/lib/tests/hash_test.c @@ -0,0 +1,202 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2024 + * + * Test of the hashing 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 <ouroboros/hash.h> +#include <ouroboros/test.h> + +#include <stdlib.h> +#include <stdint.h> +#include <assert.h> +#include <string.h> +#include <stdio.h> + +/* + * Test vectors calculated at + * https://www.lammertbies.nl/comm/info/crc-calculation.html + */ + +struct vec_entry { + char * in; + char * out; +}; + +static int test_crc32(void) +{ + int ret = 0; + + struct vec_entry vec [] = { + { "0", "f4dbdf21" }, + { "123456789", "cbf43926" }, + { "987654321", "015f0201" }, + { NULL, NULL } + }; + + struct vec_entry * cur = vec; + + TEST_START(); + + while (cur->in != NULL) { + uint8_t crc[4]; + char res[9]; + + str_hash(HASH_CRC32, crc, cur->in); + + sprintf(res, HASH_FMT32, HASH_VAL32(crc)); + if (strcmp(res, cur->out) != 0) { + printf("Hash failed %s != %s.\n", res, cur->out); + ret |= -1; + } + + ++cur; + } + + TEST_END(ret); + + return ret; +} + +static int test_md5(void) +{ + int ret = 0; + + struct vec_entry vec [] = {{ + "abc", + "900150983cd24fb0d6963f7d28e17f72" + }, { + "The quick brown fox jumps over the lazy dog", + "9e107d9d372bb6826bd81d3542a419d6" + }, { + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + "8215ef0796a20bcaaae116d3876c664a" + }, { + NULL, + NULL + }}; + + struct vec_entry * cur = vec; + + TEST_START(); + + + while (cur->in != NULL) { + uint8_t md5[16]; + char res[33]; + + str_hash(HASH_MD5, md5, cur->in); + + sprintf(res, HASH_FMT128, HASH_VAL128(md5)); + if (strcmp(res, cur->out) != 0) { + printf("Hash failed %s != %s.\n", res, cur->out); + ret |= -1; + } + + ++cur; + } + + TEST_END(ret); + + return ret; +} + +static int test_sha3(void) +{ + int ret = 0; + + uint8_t sha3[64]; + char res[129]; + + char * in = "abc"; + + char * out = + "e642824c3f8cf24ad09234ee7d3c766f" + "c9a3a5168d0c94ad73b46fdf"; + + TEST_START(); + + str_hash(HASH_SHA3_224, sha3, in); + + sprintf(res, HASH_FMT224, HASH_VAL224(sha3)); + if (strcmp(res, out) != 0) { + printf("SHA3-224 failed %s != %s", res, out); + ret |= -1; + } + + out = + "3a985da74fe225b2045c172d6bd390bd" + "855f086e3e9d525b46bfe24511431532"; + + str_hash(HASH_SHA3_256, sha3, in); + + sprintf(res, HASH_FMT256, HASH_VAL256(sha3)); + if (strcmp(res, out) != 0) { + printf("SHA3-256 failed %s != %s.\n", res, out); + ret |= -1; + } + + out = + "ec01498288516fc926459f58e2c6ad8d" + "f9b473cb0fc08c2596da7cf0e49be4b2" + "98d88cea927ac7f539f1edf228376d25"; + + str_hash(HASH_SHA3_384, sha3, in); + + sprintf(res, HASH_FMT384, HASH_VAL384(sha3)); + if (strcmp(res, out) != 0) { + printf("SHA3-384failed %s != %s.'n", res, out); + ret |= -1; + } + + out = + "b751850b1a57168a5693cd924b6b096e" + "08f621827444f70d884f5d0240d2712e" + "10e116e9192af3c91a7ec57647e39340" + "57340b4cf408d5a56592f8274eec53f0"; + + str_hash(HASH_SHA3_512, sha3, in); + + sprintf(res, HASH_FMT512, HASH_VAL512(sha3)); + if (strcmp(res, out) != 0) { + printf("SHA3-512 failed %s != %s.\n", res, out); + ret |= -1; + } + + TEST_END(ret); + + return ret; +} + +int hash_test(int argc, + char ** argv) +{ + int ret = 0; + + (void) argc; + (void) argv; + + ret |= test_crc32(); + + ret |= test_md5(); + + ret |= test_sha3(); + + return ret; +} diff --git a/src/lib/tests/md5_test.c b/src/lib/tests/md5_test.c index b5ad127f..28e8f42f 100644 --- a/src/lib/tests/md5_test.c +++ b/src/lib/tests/md5_test.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Test of the MD5 function * diff --git a/src/lib/tests/sha3_test.c b/src/lib/tests/sha3_test.c index 4860cd9b..82b4ef0d 100644 --- a/src/lib/tests/sha3_test.c +++ b/src/lib/tests/sha3_test.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Test of the SHA3 function * diff --git a/src/lib/tests/shm_rbuff_test.c b/src/lib/tests/shm_rbuff_test.c index a3ed1449..e36c3229 100644 --- a/src/lib/tests/shm_rbuff_test.c +++ b/src/lib/tests/shm_rbuff_test.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Test of the shm_rbuff * 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_utils_test.c b/src/lib/tests/time_test.c index fa65c4dc..77fecdac 100644 --- a/src/lib/tests/time_utils_test.c +++ b/src/lib/tests/time_test.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Test of the time utilities * @@ -22,18 +22,20 @@ #define _POSIX_C_SOURCE 200809L -#include <ouroboros/time_utils.h> +#include <ouroboros/time.h> #include <stdio.h> 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, @@ -66,8 +68,8 @@ static int tv_check(struct timeval * v, return v->tv_sec == sec && v->tv_usec == usec; } -int time_utils_test(int argc, - char ** argv) +int time_test(int argc, + char ** argv) { struct timespec s0; struct timespec s1; 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; +} |