diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 6338e4d88fc..f2ea4eaab11 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -375,6 +375,7 @@ if(UA_ENABLE_ENCRYPTION_MBEDTLS) ua_add_test(encryption/check_cert_generation.c) ua_add_test(encryption/check_csr_generation.c) ua_add_test(encryption/check_update_certificate.c) + ua_add_test(encryption/check_update_trustlist.c) ua_add_test(encryption/check_certificategroup.c) endif() @@ -388,6 +389,7 @@ if(UA_ENABLE_ENCRYPTION_OPENSSL OR UA_ENABLE_ENCRYPTION_LIBRESSL) ua_add_test(encryption/check_cert_generation.c) ua_add_test(encryption/check_csr_generation.c) ua_add_test(encryption/check_update_certificate.c) + ua_add_test(encryption/check_update_trustlist.c) ua_add_test(encryption/check_username_connect_none.c) ua_add_test(encryption/check_certificategroup.c) endif() diff --git a/tests/encryption/check_update_trustlist.c b/tests/encryption/check_update_trustlist.c new file mode 100644 index 00000000000..8b2b1f75b26 --- /dev/null +++ b/tests/encryption/check_update_trustlist.c @@ -0,0 +1,330 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright 2024 (c) Fraunhofer IOSB (Author: Noel Graf) + */ + +#include +#include +#include + +#include "ua_server_internal.h" + +#include +#include "test_helpers.h" +#include "certificates.h" + +#ifdef __linux__ +#include "mp_printf.h" +#include +#endif + +UA_Server *server; + +static void setup(void) { + /* Load certificate and private key */ + UA_ByteString certificate; + certificate.length = CERT_DER_LENGTH; + certificate.data = CERT_DER_DATA; + + UA_ByteString privateKey; + privateKey.length = KEY_DER_LENGTH; + privateKey.data = KEY_DER_DATA; + + server = UA_Server_newForUnitTestWithSecurityPolicies(4840, &certificate, &privateKey, + NULL, 0, NULL, 0, NULL, 0); + ck_assert(server != NULL); +} + +#ifdef __linux__ /* Linux only so far */ +static void setup2(void) { + /* Load certificate and private key */ + UA_ByteString certificate; + certificate.length = CERT_DER_LENGTH; + certificate.data = CERT_DER_DATA; + + UA_ByteString privateKey; + privateKey.length = KEY_DER_LENGTH; + privateKey.data = KEY_DER_DATA; + + char storePathDir[PATH_MAX]; + getcwd(storePathDir, PATH_MAX - 4); + mp_snprintf(storePathDir, PATH_MAX, "%s/pki", storePathDir); + + const UA_String storePath = UA_STRING(storePathDir); + server = + UA_Server_newForUnitTestWithSecurityPolicies_Filestore(4840, &certificate, + &privateKey, storePath); + ck_assert(server != NULL); +} +#endif + +static void teardown(void) { + UA_Server_delete(server); +} + +static void generateCertificate(UA_ByteString *certificate, UA_ByteString *privKey) { + UA_String subject[3] = {UA_STRING_STATIC("C=DE"), + UA_STRING_STATIC("O=SampleOrganization"), + UA_STRING_STATIC("CN=Open62541Server@localhost")}; + UA_UInt32 lenSubject = 3; + UA_String subjectAltName[2]= { + UA_STRING_STATIC("DNS:localhost"), + UA_STRING_STATIC("URI:urn:open62541.server.application") + }; + UA_UInt32 lenSubjectAltName = 2; + UA_KeyValueMap *kvm = UA_KeyValueMap_new(); + UA_UInt16 expiresIn = 14; + UA_KeyValueMap_setScalar(kvm, UA_QUALIFIEDNAME(0, "expires-in-days"), + (void *)&expiresIn, &UA_TYPES[UA_TYPES_UINT16]); + UA_UInt16 keyLength = 2048; + UA_KeyValueMap_setScalar(kvm, UA_QUALIFIEDNAME(0, "key-size-bits"), + (void *)&keyLength, &UA_TYPES[UA_TYPES_UINT16]); + UA_CreateCertificate(UA_Log_Stdout, subject, lenSubject, subjectAltName, + lenSubjectAltName, UA_CERTIFICATEFORMAT_DER, kvm, + privKey, certificate); + + UA_KeyValueMap_delete(kvm); +} + +START_TEST(add_ca_certificate_trustlist) { + UA_ServerConfig *config = UA_Server_getConfig(server); + + UA_ByteString trustedCertificates[2] = {0}; + UA_ByteString trustedCrls[2] = {0}; + + trustedCertificates[0].length = ROOT_CERT_DER_LENGTH; + trustedCertificates[0].data = ROOT_CERT_DER_DATA; + + trustedCrls[0].length = ROOT_EMPTY_CRL_PEM_LENGTH; + trustedCrls[0].data = ROOT_EMPTY_CRL_PEM_DATA; + + trustedCertificates[1].length = INTERMEDIATE_CERT_DER_LENGTH; + trustedCertificates[1].data = INTERMEDIATE_CERT_DER_DATA; + + trustedCrls[1].length = INTERMEDIATE_EMPTY_CRL_PEM_LENGTH; + trustedCrls[1].data = INTERMEDIATE_EMPTY_CRL_PEM_DATA; + + + UA_NodeId defaultApplicationGroup = UA_NODEID_NUMERIC(0, UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP); + + UA_StatusCode retval = + UA_Server_addCertificates(server, defaultApplicationGroup, trustedCertificates, 2, + trustedCrls, 2, true, true); + ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD); + + UA_TrustListDataType trustList; + UA_TrustListDataType_init(&trustList); + trustList.specifiedLists = UA_TRUSTLISTMASKS_ALL; + + retval = config->secureChannelPKI.getTrustList(&config->secureChannelPKI, &trustList); + ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD); + ck_assert_uint_eq(trustList.trustedCertificatesSize, 2); + ck_assert_uint_eq(trustList.issuerCertificatesSize, 0); + ck_assert_uint_eq(trustList.trustedCrlsSize, 2); + ck_assert_uint_eq(trustList.issuerCrlsSize, 0); + + UA_TrustListDataType_clear(&trustList); +} +END_TEST + +START_TEST(add_ca_certificate_issuerlist) { + UA_ServerConfig *config = UA_Server_getConfig(server); + + UA_ByteString issuerCertificates[2] = {0}; + UA_ByteString issuerCrls[2] = {0}; + + issuerCertificates[0].length = ROOT_CERT_DER_LENGTH; + issuerCertificates[0].data = ROOT_CERT_DER_DATA; + + issuerCrls[0].length = ROOT_EMPTY_CRL_PEM_LENGTH; + issuerCrls[0].data = ROOT_EMPTY_CRL_PEM_DATA; + + issuerCertificates[1].length = INTERMEDIATE_CERT_DER_LENGTH; + issuerCertificates[1].data = INTERMEDIATE_CERT_DER_DATA; + + issuerCrls[1].length = INTERMEDIATE_EMPTY_CRL_PEM_LENGTH; + issuerCrls[1].data = INTERMEDIATE_EMPTY_CRL_PEM_DATA; + + + UA_NodeId defaultApplicationGroup = UA_NODEID_NUMERIC(0, UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP); + + UA_StatusCode retval = + UA_Server_addCertificates(server, defaultApplicationGroup, issuerCertificates, 2, + issuerCrls, 2, false, true); + ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD); + + UA_TrustListDataType trustList; + UA_TrustListDataType_init(&trustList); + trustList.specifiedLists = UA_TRUSTLISTMASKS_ALL; + + retval = config->secureChannelPKI.getTrustList(&config->secureChannelPKI, &trustList); + ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD); + ck_assert_uint_eq(trustList.trustedCertificatesSize, 0); + ck_assert_uint_eq(trustList.issuerCertificatesSize, 2); + ck_assert_uint_eq(trustList.trustedCrlsSize, 0); + ck_assert_uint_eq(trustList.issuerCrlsSize, 2); + + UA_TrustListDataType_clear(&trustList); +} +END_TEST + +START_TEST(remove_certificate_trustlist) { + UA_ServerConfig *config = UA_Server_getConfig(server); + + UA_ByteString trustedCertificates[2] = {0}; + UA_ByteString trustedCrls[2] = {0}; + + trustedCertificates[0].length = ROOT_CERT_DER_LENGTH; + trustedCertificates[0].data = ROOT_CERT_DER_DATA; + + trustedCrls[0].length = ROOT_EMPTY_CRL_PEM_LENGTH; + trustedCrls[0].data = ROOT_EMPTY_CRL_PEM_DATA; + + trustedCertificates[1].length = INTERMEDIATE_CERT_DER_LENGTH; + trustedCertificates[1].data = INTERMEDIATE_CERT_DER_DATA; + + trustedCrls[1].length = INTERMEDIATE_EMPTY_CRL_PEM_LENGTH; + trustedCrls[1].data = INTERMEDIATE_EMPTY_CRL_PEM_DATA; + + + UA_NodeId defaultApplicationGroup = UA_NODEID_NUMERIC(0, UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP); + + UA_StatusCode retval = + UA_Server_addCertificates(server, defaultApplicationGroup, trustedCertificates, 2, + trustedCrls, 2, true, true); + ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD); + + retval = UA_Server_removeCertificates(server, defaultApplicationGroup, + trustedCertificates, 2, true); + ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD); + + UA_TrustListDataType trustList; + UA_TrustListDataType_init(&trustList); + trustList.specifiedLists = UA_TRUSTLISTMASKS_ALL; + + retval = config->secureChannelPKI.getTrustList(&config->secureChannelPKI, &trustList); + ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD); + ck_assert_uint_eq(trustList.trustedCertificatesSize, 0); + ck_assert_uint_eq(trustList.issuerCertificatesSize, 0); + ck_assert_uint_eq(trustList.trustedCrlsSize, 0); + ck_assert_uint_eq(trustList.issuerCrlsSize, 0); + + UA_TrustListDataType_clear(&trustList); +} +END_TEST + +START_TEST(remove_certificate_issuerlist) { + UA_ServerConfig *config = UA_Server_getConfig(server); + + UA_ByteString issuerCertificates[2] = {0}; + UA_ByteString issuerCrls[2] = {0}; + + issuerCertificates[0].length = ROOT_CERT_DER_LENGTH; + issuerCertificates[0].data = ROOT_CERT_DER_DATA; + + issuerCrls[0].length = ROOT_EMPTY_CRL_PEM_LENGTH; + issuerCrls[0].data = ROOT_EMPTY_CRL_PEM_DATA; + + issuerCertificates[1].length = INTERMEDIATE_CERT_DER_LENGTH; + issuerCertificates[1].data = INTERMEDIATE_CERT_DER_DATA; + + issuerCrls[1].length = INTERMEDIATE_EMPTY_CRL_PEM_LENGTH; + issuerCrls[1].data = INTERMEDIATE_EMPTY_CRL_PEM_DATA; + + + UA_NodeId defaultApplicationGroup = UA_NODEID_NUMERIC(0, UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP); + + UA_StatusCode retval = + UA_Server_addCertificates(server, defaultApplicationGroup, issuerCertificates, 2, + issuerCrls, 2, false, true); + ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD); + + retval = UA_Server_removeCertificates(server, defaultApplicationGroup, + issuerCertificates, 2, false); + ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD); + + UA_TrustListDataType trustList; + UA_TrustListDataType_init(&trustList); + trustList.specifiedLists = UA_TRUSTLISTMASKS_ALL; + + retval = config->secureChannelPKI.getTrustList(&config->secureChannelPKI, &trustList); + ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD); + ck_assert_uint_eq(trustList.trustedCertificatesSize, 0); + ck_assert_uint_eq(trustList.issuerCertificatesSize, 0); + ck_assert_uint_eq(trustList.trustedCrlsSize, 0); + ck_assert_uint_eq(trustList.issuerCrlsSize, 0); + + UA_TrustListDataType_clear(&trustList); +} +END_TEST + +START_TEST(add_application_certificate_trustlist) { + UA_ServerConfig *config = UA_Server_getConfig(server); + + UA_ByteString trustedCertificates[1] = {0}; + + trustedCertificates[0].length = APPLICATION_CERT_DER_LENGTH; + trustedCertificates[0].data = APPLICATION_CERT_DER_DATA; + + UA_NodeId defaultApplicationGroup = UA_NODEID_NUMERIC(0, UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP); + + UA_StatusCode retval = + UA_Server_addCertificates(server, defaultApplicationGroup, trustedCertificates, 1, + NULL, 0, true, true); + ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD); + + UA_TrustListDataType trustList; + UA_TrustListDataType_init(&trustList); + trustList.specifiedLists = UA_TRUSTLISTMASKS_ALL; + + retval = config->secureChannelPKI.getTrustList(&config->secureChannelPKI, &trustList); + ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD); + ck_assert_uint_eq(trustList.trustedCertificatesSize, 1); + ck_assert_uint_eq(trustList.issuerCertificatesSize, 0); + ck_assert_uint_eq(trustList.trustedCrlsSize, 0); + ck_assert_uint_eq(trustList.issuerCrlsSize, 0); + + UA_TrustListDataType_clear(&trustList); +} +END_TEST + +static Suite* testSuite_create_certificate(void) { + Suite *s = suite_create("Update Trustlist"); + TCase *tc_cert = tcase_create("Update Trustlist"); + tcase_add_checked_fixture(tc_cert, setup, teardown); +#ifdef UA_ENABLE_ENCRYPTION + tcase_add_test(tc_cert, add_ca_certificate_trustlist); + tcase_add_test(tc_cert, add_ca_certificate_issuerlist); + tcase_add_test(tc_cert, remove_certificate_trustlist); + tcase_add_test(tc_cert, remove_certificate_issuerlist); + tcase_add_test(tc_cert, add_application_certificate_trustlist); +#endif /* UA_ENABLE_ENCRYPTION */ + suite_add_tcase(s,tc_cert); + +#ifdef __linux__ /* Linux only so far */ + TCase *tc_cert_filestore = tcase_create("Update Certificate Filestore"); + tcase_add_checked_fixture(tc_cert_filestore, setup2, teardown); +#ifdef UA_ENABLE_ENCRYPTION + tcase_add_test(tc_cert, add_ca_certificate_trustlist); + tcase_add_test(tc_cert, add_ca_certificate_issuerlist); + tcase_add_test(tc_cert, remove_certificate_trustlist); + tcase_add_test(tc_cert, remove_certificate_issuerlist); + tcase_add_test(tc_cert, add_application_certificate_trustlist); +#endif /* UA_ENABLE_ENCRYPTION */ + suite_add_tcase(s,tc_cert_filestore); +#endif + + return s; +} + +int main(void) { + Suite *s = testSuite_create_certificate(); + SRunner *sr = srunner_create(s); + srunner_set_fork_status(sr, CK_NOFORK); + srunner_run_all(sr,CK_NORMAL); + int number_failed = srunner_ntests_failed(sr); + srunner_free(sr); + return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; +}