From 12989671c9f43707701a8cef8e77e34b1bf24a37 Mon Sep 17 00:00:00 2001 From: Thomas Vanbesien Date: Wed, 18 Feb 2026 12:54:24 +0100 Subject: Make client encryption optional certificate, privateKey, and trustStore are now optional config keys using the same all-or-none pattern as the server programs. When all three are omitted the client connects without encryption via UA_ClientConfig_setDefault; when present, securityMode and securityPolicy are required and the secure path is used as before. --- src/client.c | 113 ++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 73 insertions(+), 40 deletions(-) (limited to 'src') diff --git a/src/client.c b/src/client.c index ccb1021..4c02a57 100644 --- a/src/client.c +++ b/src/client.c @@ -6,11 +6,16 @@ * find-servers — queries a server's FindServers service * get-endpoints — queries a server's GetEndpoints service * read-time — connects to a server and reads the current time + * + * Encryption is optional: when certificate, privateKey, and trustStore are + * provided, the client uses the configured security policy; otherwise it + * connects without encryption. */ #include "common.h" #include "config.h" +#include #include #include @@ -201,31 +206,26 @@ main (int argc, char **argv) const char *applicationUri = configRequire (&cfg, "applicationUri", "Client"); - const char *certPath = configRequire (&cfg, "certificate", "Client"); - const char *keyPath = configRequire (&cfg, "privateKey", "Client"); - const char *secModeStr = configRequire (&cfg, "securityMode", "Client"); - const char *secPolStr = configRequire (&cfg, "securityPolicy", "Client"); - - if (!applicationUri || !certPath || !keyPath || !secModeStr || !secPolStr) + if (!applicationUri) { configFree (&cfg); return EXIT_FAILURE; } - UA_MessageSecurityMode secMode = parseSecurityMode (secModeStr); - if (secMode == UA_MESSAGESECURITYMODE_INVALID) - { - UA_LOG_FATAL (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, - "Unknown security mode: %s", secModeStr); - configFree (&cfg); - return EXIT_FAILURE; - } + /* Security configuration (optional). When certificate, privateKey, and + trustStore are all omitted the client connects without encryption. + When any of the three is present, all three are required. */ + const char *certPath = configGet (&cfg, "certificate"); + const char *keyPath = configGet (&cfg, "privateKey"); + const char *trustStore = configGet (&cfg, "trustStore"); + UA_Boolean secure + = (certPath != NULL || keyPath != NULL || trustStore != NULL); - const char *secPolUri = resolveSecurityPolicyUri (secPolStr); - if (!secPolUri) + if (secure && (!certPath || !keyPath || !trustStore)) { UA_LOG_FATAL (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, - "Unknown security policy: %s", secPolStr); + "Incomplete security config: certificate, privateKey, and " + "trustStore must all be set, or all omitted"); configFree (&cfg); return EXIT_FAILURE; } @@ -241,36 +241,69 @@ main (int argc, char **argv) return EXIT_FAILURE; } - /* ---- Trust store ---- */ - - const char *trustStore = configRequire (&cfg, "trustStore", "Client"); - if (!trustStore) - { - configFree (&cfg); - return EXIT_FAILURE; - } + /* ---- Create client ---- */ + UA_Client *client = UA_Client_new (); char **trustPaths = NULL; size_t trustSize = 0; - if (loadTrustStore (trustStore, &trustPaths, &trustSize) != 0) + + if (secure) { - configFree (&cfg); - return EXIT_FAILURE; + const char *secModeStr = configRequire (&cfg, "securityMode", "Client"); + const char *secPolStr = configRequire (&cfg, "securityPolicy", "Client"); + if (!secModeStr || !secPolStr) + { + UA_Client_delete (client); + configFree (&cfg); + return EXIT_FAILURE; + } + + UA_MessageSecurityMode secMode = parseSecurityMode (secModeStr); + if (secMode == UA_MESSAGESECURITYMODE_INVALID) + { + UA_LOG_FATAL (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, + "Unknown security mode: %s", secModeStr); + UA_Client_delete (client); + configFree (&cfg); + return EXIT_FAILURE; + } + + const char *secPolUri = resolveSecurityPolicyUri (secPolStr); + if (!secPolUri) + { + UA_LOG_FATAL (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, + "Unknown security policy: %s", secPolStr); + UA_Client_delete (client); + configFree (&cfg); + return EXIT_FAILURE; + } + + if (loadTrustStore (trustStore, &trustPaths, &trustSize) != 0) + { + UA_Client_delete (client); + configFree (&cfg); + return EXIT_FAILURE; + } + + UA_StatusCode retval = createSecureClientConfig ( + UA_Client_getConfig (client), applicationUri, certPath, keyPath, + trustPaths, trustSize, secMode, secPolUri); + if (retval != UA_STATUSCODE_GOOD) + { + UA_Client_delete (client); + freeTrustStore (trustPaths, trustSize); + configFree (&cfg); + return EXIT_FAILURE; + } } - - /* ---- Create client ---- */ - - UA_Client *client = UA_Client_new (); - UA_StatusCode retval = createSecureClientConfig ( - UA_Client_getConfig (client), applicationUri, certPath, keyPath, - trustPaths, trustSize, secMode, secPolUri); - if (retval != UA_STATUSCODE_GOOD) + else { - UA_Client_delete (client); - freeTrustStore (trustPaths, trustSize); - configFree (&cfg); - return EXIT_FAILURE; + UA_ClientConfig *cc = UA_Client_getConfig (client); + UA_ClientConfig_setDefault (cc); + UA_String_clear (&cc->clientDescription.applicationUri); + cc->clientDescription.applicationUri = UA_STRING_ALLOC (applicationUri); } + UA_Client_getConfig (client)->logging->context = (void *)(uintptr_t)logLevel; /* ---- Dispatch operation ---- */ -- cgit v1.2.3