Coverage Report

Created: 2026-07-16 06:23

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/open62541_15/plugins/ua_config_default.c
Line
Count
Source
1
/* This work is licensed under a Creative Commons CCZero 1.0 Universal License.
2
 * See http://creativecommons.org/publicdomain/zero/1.0/ for more information.
3
 *
4
 *    Copyright 2017 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
5
 *    Copyright 2017 (c) Julian Grothoff
6
 *    Copyright 2017-2018 (c) Mark Giraud, Fraunhofer IOSB
7
 *    Copyright 2017 (c) Stefan Profanter, fortiss GmbH
8
 *    Copyright 2017 (c) Thomas Stalder, Blue Time Concept SA
9
 *    Copyright 2018 (c) Daniel Feist, Precitec GmbH & Co. KG
10
 *    Copyright 2018 (c) Fabian Arndt, Root-Core
11
 *    Copyright 2019 (c) Kalycito Infotech Private Limited
12
 *    Copyright 2017-2020 (c) HMS Industrial Networks AB (Author: Jonas Green)
13
 *    Copyright 2020 (c) Wind River Systems, Inc.
14
 *    Copyright 2024 (c) Siemens AG (Authors: Tin Raic, Thomas Zeschg)
15
 *    Copyright 2026 (c) o6 Automation GmbH (Author: Andreas Ebner)
16
 */
17
18
#include <open62541/plugin/accesscontrol_default.h>
19
#include <open62541/plugin/nodestore_default.h>
20
#include <open62541/plugin/log_stdout.h>
21
#include <open62541/plugin/certificategroup_default.h>
22
#include <open62541/plugin/securitypolicy_default.h>
23
#include <open62541/server_config_default.h>
24
#if defined(UA_ENABLE_DISCOVERY) || defined(UA_ENABLE_AMALGAMATION)
25
#include <open62541/client.h>
26
#include <open62541/client_config_default.h>
27
#endif
28
29
#include "../deps/mp_printf.h"
30
31
#if defined(UA_ENABLE_ENCRYPTION_MBEDTLS)
32
#include <mbedtls/version.h>
33
#endif
34
35
#include <stdio.h>
36
#ifdef UA_ARCHITECTURE_WIN32
37
# include <winsock2.h>
38
#else
39
# include <unistd.h>
40
#endif
41
42
/* Struct initialization works across ANSI C/C99/C++ if it is done when the
43
 * variable is first declared. Assigning values to existing structs is
44
 * heterogeneous across the three. */
45
static UA_INLINE UA_UInt32Range
46
40.5k
UA_UINT32RANGE(UA_UInt32 min, UA_UInt32 max) {
47
40.5k
    UA_UInt32Range range = {min, max};
48
40.5k
    return range;
49
40.5k
}
50
51
static UA_INLINE UA_DurationRange
52
27.0k
UA_DURATIONRANGE(UA_Duration min, UA_Duration max) {
53
27.0k
    UA_DurationRange range = {min, max};
54
27.0k
    return range;
55
27.0k
}
56
57
/* Request the private key password from stdin if no callback is defined */
58
#ifdef UA_ENABLE_ENCRYPTION
59
static UA_StatusCode
60
0
readPrivateKeyPassword(UA_ByteString *password) {
61
    /* Read from stdin */
62
0
    char buf[256];
63
0
    fputs("Private key requires a password. Enter and press return: ", stdout);
64
0
    char *s = fgets(buf, 256, stdin);
65
0
    if(!s)
66
0
        return UA_STATUSCODE_BADINTERNALERROR;
67
68
    /* Get rid of any trailing \n */
69
0
    size_t len = strlen(buf);
70
0
    if(len == 0)
71
0
        return UA_STATUSCODE_BADINTERNALERROR;
72
0
    if(buf[len-1] == '\n')
73
0
        buf[len-1] = 0;
74
75
0
    *password = UA_BYTESTRING_ALLOC(buf);
76
0
    return UA_STATUSCODE_GOOD;
77
0
}
78
#endif
79
80
UA_Server *
81
0
UA_Server_new(void) {
82
0
    UA_ServerConfig config;
83
0
    memset(&config, 0, sizeof(UA_ServerConfig));
84
0
    UA_StatusCode res = UA_ServerConfig_setDefault(&config);
85
0
    if(res != UA_STATUSCODE_GOOD)
86
0
        return NULL;
87
0
    return UA_Server_newWithConfig(&config);
88
0
}
89
90
#if defined(UA_ARCHITECTURE_POSIX) || defined(UA_ARCHITECTURE_WIN32) || defined(UA_ARCHITECTURE_ZEPHYR)
91
/* Required for the definition of SIGINT */
92
#include <signal.h>
93
94
struct InterruptContext {
95
    UA_Server *server;
96
    UA_Boolean running;
97
};
98
99
static void
100
0
shutdownServer(UA_Server *server, void *context) {
101
0
    struct InterruptContext *ic = (struct InterruptContext*)context;
102
0
    UA_ServerConfig *config = UA_Server_getConfig(ic->server);
103
0
    UA_LOG_INFO(config->logging, UA_LOGCATEGORY_APPLICATION,
104
0
                "Stopping the server");
105
0
    ic->running = false;
106
0
}
107
108
static void
109
interruptServer(UA_InterruptManager *im, uintptr_t interruptHandle,
110
0
                void *context, const UA_KeyValueMap *parameters) {
111
0
    struct InterruptContext *ic = (struct InterruptContext*)context;
112
0
    UA_ServerConfig *config = UA_Server_getConfig(ic->server);
113
114
0
    if(config->shutdownDelay <= 0.0) {
115
0
        UA_LOG_INFO(config->logging, UA_LOGCATEGORY_APPLICATION,
116
0
                    "Received SIGINT interrupt. Stopping the server.");
117
0
        ic->running = false;
118
0
        return;
119
0
    }
120
121
0
    UA_LOG_INFO(config->logging, UA_LOGCATEGORY_APPLICATION,
122
0
                "Received SIGINT interrupt. Stopping the server in %.2fs.",
123
0
                config->shutdownDelay / 1000.0);
124
125
0
    UA_UInt32 secondsTillShutdown = (UA_UInt32)(config->shutdownDelay / 1000.0);
126
0
    UA_Variant val;
127
0
    UA_Variant_setScalar(&val, &secondsTillShutdown, &UA_TYPES[UA_TYPES_UINT32]);
128
0
    UA_Server_writeValue(ic->server, UA_NS0ID(SERVER_SERVERSTATUS_SECONDSTILLSHUTDOWN), val);
129
0
    UA_Server_addTimedCallback(ic->server, shutdownServer, ic, UA_DateTime_nowMonotonic() +
130
0
                               (UA_DateTime)(config->shutdownDelay * UA_DATETIME_MSEC), NULL);
131
132
    /* Notify the application that the server is stopping */
133
0
    if(config->notifyLifecycleState)
134
0
        config->notifyLifecycleState(ic->server, UA_LIFECYCLESTATE_STOPPING);
135
0
}
136
137
UA_StatusCode
138
0
UA_Server_runUntilInterrupt(UA_Server *server) {
139
0
    if(!server)
140
0
        return UA_STATUSCODE_BADINTERNALERROR;
141
0
    UA_ServerConfig *config = UA_Server_getConfig(server);
142
0
    UA_EventLoop *el = config->eventLoop;
143
0
    if(!el)
144
0
        return UA_STATUSCODE_BADINTERNALERROR;
145
146
    /* Get the interrupt manager */
147
0
    UA_EventSource *es = el->eventSources;
148
0
    while(es) {
149
0
        if(es->eventSourceType == UA_EVENTSOURCETYPE_INTERRUPTMANAGER)
150
0
            break;
151
0
        es = es->next;
152
0
    }
153
0
    if(!es) {
154
0
        UA_LOG_ERROR(config->logging, UA_LOGCATEGORY_APPLICATION,
155
0
                       "No Interrupt EventSource configured");
156
0
        return UA_STATUSCODE_BADINTERNALERROR;
157
0
    }
158
0
    UA_InterruptManager *im = (UA_InterruptManager*)es;
159
160
    /* Register the interrupt */
161
0
    struct InterruptContext ic;
162
0
    ic.server = server;
163
0
    ic.running = true;
164
0
    UA_StatusCode retval =
165
0
        im->registerInterrupt(im, SIGINT, &UA_KEYVALUEMAP_NULL,
166
0
                              interruptServer, &ic);
167
0
    if(retval != UA_STATUSCODE_GOOD) {
168
0
        UA_LOG_ERROR(config->logging, UA_LOGCATEGORY_APPLICATION,
169
0
                     "Could not register the interrupt with status code %s",
170
0
                     UA_StatusCode_name(retval));
171
0
        return retval;
172
0
    }
173
174
    /* Run the server */
175
0
    retval = UA_Server_run_startup(server);
176
0
    if(retval != UA_STATUSCODE_GOOD)
177
0
        goto deregister_interrupt;
178
0
    while(ic.running) {
179
0
        UA_Server_run_iterate(server, true);
180
0
    }
181
182
    /* Shut down the server */
183
0
    retval = UA_Server_run_shutdown(server);
184
185
    /* Deregister the interrupt */
186
0
 deregister_interrupt:
187
0
    im->deregisterInterrupt(im, SIGINT);
188
0
    return retval;
189
0
}
190
191
#endif /* defined(UA_ARCHITECTURE_POSIX) || defined(UA_ARCHITECTURE_WIN32) */
192
193
/*******************************/
194
/* Default Connection Settings */
195
/*******************************/
196
197
const UA_ConnectionConfig UA_ConnectionConfig_default = {
198
    0,       /* .protocolVersion */
199
    1 << 16, /* .sendBufferSize, 64k per chunk */
200
    1 << 16, /* .recvBufferSize, 64k per chunk */
201
    1 << 29, /* .localMaxMessageSize, 512 MB */
202
    1 << 29, /* .remoteMaxMessageSize, 512 MB */
203
    1 << 14, /* .localMaxChunkCount, 16k */
204
    1 << 14  /* .remoteMaxChunkCount, 16k */
205
};
206
207
/***************************/
208
/* Default Server Settings */
209
/***************************/
210
211
#define MANUFACTURER_NAME "open62541"
212
#define PRODUCT_NAME "open62541 OPC UA Server"
213
#define PRODUCT_URI "http://open62541.org"
214
13.5k
#define APPLICATION_NAME "open62541-based OPC UA Application"
215
#define APPLICATION_URI "urn:open62541.unconfigured.application"
216
217
/* Upper bound */
218
#define SECURITY_POLICY_SIZE 14
219
220
#define STRINGIFY(arg) #arg
221
#define VERSION(MAJOR, MINOR, PATCH, LABEL) \
222
    STRINGIFY(MAJOR) "." STRINGIFY(MINOR) "." STRINGIFY(PATCH) LABEL
223
224
static UA_StatusCode
225
addEndpoint(UA_ServerConfig *conf,
226
            const UA_SecurityPolicy *securityPolicy,
227
13.5k
            UA_MessageSecurityMode securityMode) {
228
    /* Test if the endpoint already exists */
229
13.5k
    for(size_t i = 0; i < conf->endpointsSize; i++) {
230
0
        UA_EndpointDescription *ep = &conf->endpoints[i];
231
0
        if(!UA_String_equal(&securityPolicy->policyUri, &ep->securityPolicyUri))
232
0
            continue;
233
0
        if(ep->securityMode != securityMode)
234
0
            continue;
235
0
        return UA_STATUSCODE_GOOD;
236
0
    }
237
238
    /* Reallocate the array size */
239
13.5k
    UA_EndpointDescription *tmp = (UA_EndpointDescription *)
240
13.5k
        UA_realloc(conf->endpoints,
241
13.5k
                   sizeof(UA_EndpointDescription) * (1 + conf->endpointsSize));
242
13.5k
    if(!tmp)
243
0
        return UA_STATUSCODE_BADOUTOFMEMORY;
244
13.5k
    conf->endpoints = tmp;
245
246
    /* The following fields are overwritten internally with up-to-date
247
     * information from the server config:
248
     *
249
     * UserTokenPolicies
250
     * ApplicationDescription (server)
251
     * ServerCertificate
252
     * EndpointURL */
253
13.5k
    UA_EndpointDescription *endpoint = &conf->endpoints[conf->endpointsSize];
254
13.5k
    UA_EndpointDescription_init(endpoint);
255
13.5k
    endpoint->transportProfileUri =
256
13.5k
        UA_STRING_ALLOC("http://opcfoundation.org/UA-Profile/Transport/uatcp-uasc-uabinary");
257
13.5k
    endpoint->securityMode = securityMode;
258
13.5k
    endpoint->securityLevel = securityPolicy->securityLevel;
259
260
13.5k
    UA_StatusCode retval = UA_String_copy(&securityPolicy->policyUri,
261
13.5k
                                          &endpoint->securityPolicyUri);
262
263
13.5k
    if(retval == UA_STATUSCODE_GOOD) {
264
13.5k
        conf->endpointsSize++;
265
13.5k
    } else {
266
0
        UA_EndpointDescription_clear(endpoint);
267
0
        if(conf->endpointsSize == 0) {
268
0
            UA_free(conf->endpoints);
269
0
            conf->endpoints = NULL;
270
0
        }
271
0
    }
272
273
13.5k
    return retval;
274
13.5k
}
275
276
static UA_StatusCode
277
13.5k
setDefaultConfig(UA_ServerConfig *conf, UA_UInt16 portNumber) {
278
13.5k
    if(!conf)
279
0
        return UA_STATUSCODE_BADINVALIDARGUMENT;
280
281
    /* NodeStore */
282
13.5k
    if(!conf->nodestore)
283
13.5k
        conf->nodestore = UA_Nodestore_ZipTree();
284
285
    /* Logging */
286
13.5k
    if(conf->logging == NULL)
287
13.5k
        conf->logging = UA_Log_Stdout_new(UA_LOGLEVEL_INFO);
288
289
    /* EventLoop */
290
13.5k
    if(conf->eventLoop == NULL) {
291
#if defined(UA_ARCHITECTURE_ZEPHYR)
292
        conf->eventLoop = UA_EventLoop_new_Zephyr(conf->logging);
293
#elif defined(UA_ARCHITECTURE_LWIP)
294
        conf->eventLoop = UA_EventLoop_new_LWIP(conf->logging, NULL);
295
#else
296
13.5k
        conf->eventLoop = UA_EventLoop_new_POSIX(conf->logging);
297
13.5k
#endif
298
13.5k
        if(conf->eventLoop == NULL)
299
0
            return UA_STATUSCODE_BADOUTOFMEMORY;
300
301
13.5k
        conf->externalEventLoop = false;
302
303
        /* Add the TCP connection manager */
304
#if defined(UA_ARCHITECTURE_ZEPHYR)
305
        UA_ConnectionManager *tcpCM =
306
            UA_ConnectionManager_new_Zephyr_TCP(UA_STRING("tcp connection manager"));
307
#elif defined(UA_ARCHITECTURE_LWIP)
308
        UA_ConnectionManager *tcpCM =
309
            UA_ConnectionManager_new_LWIP_TCP(UA_STRING("tcp connection manager"));
310
#else
311
13.5k
        UA_ConnectionManager *tcpCM =
312
13.5k
            UA_ConnectionManager_new_POSIX_TCP(UA_STRING("tcp connection manager"));
313
13.5k
#endif
314
13.5k
        if(tcpCM)
315
13.5k
            conf->eventLoop->registerEventSource(conf->eventLoop, (UA_EventSource *)tcpCM);
316
317
        /* Add the UDP connection manager */
318
#if defined(UA_ARCHITECTURE_LWIP)
319
        UA_ConnectionManager *udpCM =
320
            UA_ConnectionManager_new_LWIP_UDP(UA_STRING("udp connection manager"));
321
        if(udpCM)
322
            conf->eventLoop->registerEventSource(conf->eventLoop, (UA_EventSource *)udpCM);
323
#elif !defined(UA_ARCHITECTURE_ZEPHYR)
324
        UA_ConnectionManager *udpCM =
325
13.5k
            UA_ConnectionManager_new_POSIX_UDP(UA_STRING("udp connection manager"));
326
13.5k
        if(udpCM)
327
13.5k
            conf->eventLoop->registerEventSource(conf->eventLoop, (UA_EventSource *)udpCM);
328
13.5k
#endif
329
330
        /* Add the Ethernet connection manager */
331
13.5k
#if !defined(UA_ARCHITECTURE_ZEPHYR) && !defined(UA_ARCHITECTURE_LWIP) && defined(UA_ARCHITECTURE_POSIX) && (defined(__linux__))
332
13.5k
        UA_ConnectionManager *ethCM =
333
13.5k
            UA_ConnectionManager_new_POSIX_Ethernet(UA_STRING("eth connection manager"));
334
13.5k
        if(ethCM)
335
13.5k
            conf->eventLoop->registerEventSource(conf->eventLoop, (UA_EventSource *)ethCM);
336
13.5k
#endif
337
338
13.5k
#if !defined(UA_ARCHITECTURE_ZEPHYR) && !defined(UA_ARCHITECTURE_LWIP)
339
        /* Add the interrupt manager */
340
13.5k
        UA_InterruptManager *im = UA_InterruptManager_new_POSIX(UA_STRING("interrupt manager"));
341
13.5k
        if(im) {
342
13.5k
            conf->eventLoop->registerEventSource(conf->eventLoop, &im->eventSource);
343
13.5k
        } else {
344
0
            UA_LOG_ERROR(conf->logging, UA_LOGCATEGORY_APPLICATION,
345
0
                         "Cannot create the Interrupt Manager (only relevant if used)");
346
0
        }
347
13.5k
#endif
348
#ifdef UA_ENABLE_MQTT
349
        /* Add the MQTT connection manager */
350
        UA_ConnectionManager *mqttCM =
351
            UA_ConnectionManager_new_MQTT(UA_STRING("mqtt connection manager"));
352
        if(mqttCM)
353
            conf->eventLoop->registerEventSource(conf->eventLoop, (UA_EventSource *)mqttCM);
354
#endif
355
13.5k
    }
356
13.5k
    if(conf->eventLoop != NULL) {
357
13.5k
        if(conf->eventLoop->state != UA_EVENTLOOPSTATE_STARTED) {
358
13.5k
            UA_StatusCode statusCode = conf->eventLoop->start(conf->eventLoop);
359
13.5k
            if(statusCode != UA_STATUSCODE_GOOD) {
360
0
                return statusCode;
361
0
            }
362
13.5k
        }
363
13.5k
    }
364
365
    /* If a second server is started later it can "steal" the port.
366
     * Having port reuse enabled is important for development.
367
     * Otherwise a long TCP TIME_WAIT is required before the port can be used again. */
368
13.5k
    conf->tcpReuseAddr = true;
369
370
    /* --> Start setting the default static config <-- */
371
372
13.5k
    conf->shutdownDelay = 0.0;
373
374
    /* Server Description */
375
13.5k
    UA_BuildInfo_clear(&conf->buildInfo);
376
13.5k
    conf->buildInfo.productUri = UA_STRING_ALLOC(PRODUCT_URI);
377
13.5k
    conf->buildInfo.manufacturerName = UA_STRING_ALLOC(MANUFACTURER_NAME);
378
13.5k
    conf->buildInfo.productName = UA_STRING_ALLOC(PRODUCT_NAME);
379
13.5k
    conf->buildInfo.softwareVersion =
380
13.5k
        UA_STRING_ALLOC(VERSION(UA_OPEN62541_VER_MAJOR, UA_OPEN62541_VER_MINOR,
381
13.5k
                                UA_OPEN62541_VER_PATCH, UA_OPEN62541_VER_LABEL));
382
13.5k
    conf->buildInfo.buildNumber = UA_STRING_ALLOC(__DATE__ " " __TIME__);
383
13.5k
    conf->buildInfo.buildDate = UA_DateTime_now();
384
385
13.5k
    UA_ApplicationDescription_clear(&conf->applicationDescription);
386
13.5k
    conf->applicationDescription.applicationUri = UA_STRING_ALLOC(APPLICATION_URI);
387
13.5k
    conf->applicationDescription.productUri = UA_STRING_ALLOC(PRODUCT_URI);
388
13.5k
    conf->applicationDescription.applicationName =
389
13.5k
        UA_LOCALIZEDTEXT_ALLOC("en", APPLICATION_NAME);
390
13.5k
    conf->applicationDescription.applicationType = UA_APPLICATIONTYPE_SERVER;
391
    /* conf->applicationDescription.gatewayServerUri = UA_STRING_NULL; */
392
    /* conf->applicationDescription.discoveryProfileUri = UA_STRING_NULL; */
393
    /* conf->applicationDescription.discoveryUrlsSize = 0; */
394
    /* conf->applicationDescription.discoveryUrls = NULL; */
395
396
13.5k
#ifdef UA_ENABLE_DISCOVERY_MULTICAST
397
13.5k
    UA_MdnsDiscoveryConfiguration_clear(&conf->mdnsConfig);
398
13.5k
# ifdef UA_ENABLE_DISCOVERY_MULTICAST_MDNSD
399
13.5k
    conf->mdnsInterfaceIP = UA_STRING_NULL;
400
#  if !defined(UA_HAS_GETIFADDR)
401
    conf->mdnsIpAddressList = NULL;
402
    conf->mdnsIpAddressListSize = 0;
403
#  endif
404
13.5k
# endif
405
13.5k
#endif
406
407
    /* Custom DataTypes */
408
    /* conf->customDataTypesSize = 0; */
409
    /* conf->customDataTypes = NULL; */
410
411
    /* Networking */
412
    /* Set up the local ServerUrls. They are used during startup to initialize
413
     * the server sockets. */
414
13.5k
    UA_String serverUrls[1];
415
13.5k
    size_t serverUrlsSize = 0;
416
13.5k
    char serverUrlBuffer[1][512];
417
418
13.5k
    if(portNumber == 0) {
419
0
        UA_LOG_WARNING(conf->logging, UA_LOGCATEGORY_APPLICATION,
420
0
                       "Dynamic port assignment will be used.");
421
0
    }
422
423
13.5k
    if(conf->serverUrlsSize > 0) {
424
0
        UA_LOG_WARNING(conf->logging, UA_LOGCATEGORY_APPLICATION,
425
0
                       "ServerUrls already set. Overriding.");
426
0
        UA_Array_delete(conf->serverUrls, conf->serverUrlsSize,
427
0
                        &UA_TYPES[UA_TYPES_STRING]);
428
0
        conf->serverUrls = NULL;
429
0
        conf->serverUrlsSize = 0;
430
0
    }
431
432
    /* Listen on all interfaces (also external). This must be the first
433
     * entry if this is desired. Otherwise some interfaces may be blocked
434
     * (already in use) with a hostname that is only locally reachable.*/
435
13.5k
    mp_snprintf(serverUrlBuffer[0], sizeof(serverUrlBuffer[0]),
436
13.5k
                "opc.tcp://:%u", portNumber);
437
13.5k
    serverUrls[serverUrlsSize] = UA_STRING(serverUrlBuffer[0]);
438
13.5k
    serverUrlsSize++;
439
440
    /* Add to the config */
441
13.5k
    UA_StatusCode retval =
442
13.5k
        UA_Array_copy(serverUrls, serverUrlsSize,
443
13.5k
                      (void**)&conf->serverUrls, &UA_TYPES[UA_TYPES_STRING]);
444
13.5k
    if(retval != UA_STATUSCODE_GOOD)
445
0
        return retval;
446
13.5k
    conf->serverUrlsSize = serverUrlsSize;
447
448
    /* Endpoints */
449
    /* conf->endpoints = {0, NULL}; */
450
451
    /* Set Logger for Certificate Verification */
452
13.5k
    if(!conf->secureChannelPKI.logging)
453
13.5k
        conf->secureChannelPKI.logging = conf->logging;
454
13.5k
    if(!conf->sessionPKI.logging)
455
13.5k
        conf->sessionPKI.logging = conf->logging;
456
457
13.5k
#ifdef UA_ENABLE_ENCRYPTION
458
    /* Limits for TrustList */
459
13.5k
    conf->maxTrustListSize = 0;
460
13.5k
    conf->maxRejectedListSize = 0;
461
13.5k
#endif
462
463
    /* Certificate Verification that accepts every certificate. Can be
464
     * overwritten when the policy is specialized. */
465
13.5k
    UA_CertificateGroup_AcceptAll(&conf->secureChannelPKI);
466
13.5k
    UA_CertificateGroup_AcceptAll(&conf->sessionPKI);
467
468
    /* * Global Node Lifecycle * */
469
    /* conf->nodeLifecycle.constructor = NULL; */
470
    /* conf->nodeLifecycle.destructor = NULL; */
471
    /* conf->nodeLifecycle.createOptionalChild = NULL; */
472
    /* conf->nodeLifecycle.generateChildNodeId = NULL; */
473
13.5k
    conf->modellingRulesOnInstances = true;
474
475
    /* Limits for SecureChannels */
476
13.5k
    conf->maxSecureChannels = 100;
477
13.5k
    conf->maxSecurityTokenLifetime = 10 * 60 * 1000; /* 10 minutes */
478
479
    /* Limits for Sessions */
480
13.5k
    conf->maxSessions = 100;
481
13.5k
    conf->maxSessionTimeout = 60.0 * 60.0 * 1000.0; /* 1h */
482
483
13.5k
#ifdef UA_ENABLE_SUBSCRIPTIONS
484
    /* Limits for Subscriptions */
485
13.5k
    conf->publishingIntervalLimits = UA_DURATIONRANGE(100.0, 3600.0 * 1000.0);
486
13.5k
    conf->lifeTimeCountLimits = UA_UINT32RANGE(3, 15000);
487
13.5k
    conf->keepAliveCountLimits = UA_UINT32RANGE(1, 100);
488
13.5k
    conf->maxNotificationsPerPublish = 1000;
489
13.5k
    conf->enableRetransmissionQueue = true;
490
13.5k
    conf->maxRetransmissionQueueSize = 0; /* unlimited */
491
13.5k
# ifdef UA_ENABLE_SUBSCRIPTIONS_EVENTS
492
13.5k
    conf->maxEventsPerNode = 0; /* unlimited */
493
13.5k
# endif
494
495
    /* Limits for MonitoredItems */
496
13.5k
    conf->samplingIntervalLimits = UA_DURATIONRANGE(50.0, 24.0 * 3600.0 * 1000.0);
497
13.5k
    conf->queueSizeLimits = UA_UINT32RANGE(1, 100);
498
13.5k
#endif
499
500
13.5k
#ifdef UA_ENABLE_DISCOVERY
501
13.5k
    conf->discoveryCleanupTimeout = 60 * 60;
502
13.5k
#endif
503
504
13.5k
#ifdef UA_ENABLE_HISTORIZING
505
    /* conf->accessHistoryDataCapability = false; */
506
    /* conf->maxReturnDataValues = 0; */
507
508
    /* conf->accessHistoryEventsCapability = false; */
509
    /* conf->maxReturnEventValues = 0; */
510
511
    /* conf->insertDataCapability = false; */
512
    /* conf->insertEventCapability = false; */
513
    /* conf->insertAnnotationsCapability = false; */
514
515
    /* conf->replaceDataCapability = false; */
516
    /* conf->replaceEventCapability = false; */
517
518
    /* conf->updateDataCapability = false; */
519
    /* conf->updateEventCapability = false; */
520
521
    /* conf->deleteRawCapability = false; */
522
    /* conf->deleteEventCapability = false; */
523
    /* conf->deleteAtTimeDataCapability = false; */
524
13.5k
#endif
525
526
13.5k
#if UA_MULTITHREADING >= 100
527
13.5k
    conf->maxAsyncOperationQueueSize = 0;
528
13.5k
    conf->asyncOperationTimeout = 120000; /* Async Operation Timeout in ms (2 minutes) */
529
13.5k
#endif
530
531
13.5k
#ifdef UA_ENABLE_PUBSUB
532
13.5k
    conf->pubsubEnabled = true;
533
13.5k
    conf->pubSubConfig.enableDeltaFrames = true;
534
13.5k
#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL
535
13.5k
    conf->pubSubConfig.enableInformationModelMethods = true;
536
13.5k
#endif
537
13.5k
#endif
538
539
    /* --> Finish setting the default static config <-- */
540
541
13.5k
    return UA_STATUSCODE_GOOD;
542
13.5k
}
543
544
UA_EXPORT UA_StatusCode
545
0
UA_ServerConfig_setBasics(UA_ServerConfig* conf) {
546
0
    return UA_ServerConfig_setBasics_withPort(conf, 4840);
547
0
}
548
549
UA_EXPORT UA_StatusCode
550
0
UA_ServerConfig_setBasics_withPort(UA_ServerConfig* conf, UA_UInt16 portNumber) {
551
0
    return setDefaultConfig(conf, portNumber);
552
0
}
553
554
UA_EXPORT UA_StatusCode
555
UA_ServerConfig_addSecurityPolicyNone(UA_ServerConfig *config,
556
13.5k
                                      const UA_ByteString *certificate) {
557
    /* Allocate the SecurityPolicies */
558
13.5k
    UA_SecurityPolicy *tmp = (UA_SecurityPolicy *)
559
13.5k
        UA_realloc(config->securityPolicies,
560
13.5k
                   sizeof(UA_SecurityPolicy) * (1 + config->securityPoliciesSize));
561
13.5k
    if(!tmp)
562
0
        return UA_STATUSCODE_BADOUTOFMEMORY;
563
13.5k
    config->securityPolicies = tmp;
564
565
    /* Populate the SecurityPolicies */
566
13.5k
    UA_ByteString localCertificate = UA_BYTESTRING_NULL;
567
13.5k
    if(certificate)
568
0
        localCertificate = *certificate;
569
13.5k
    UA_StatusCode retval =
570
13.5k
        UA_SecurityPolicy_None(&config->securityPolicies[config->securityPoliciesSize],
571
13.5k
                               localCertificate, config->logging);
572
13.5k
    if(retval != UA_STATUSCODE_GOOD) {
573
0
        if(config->securityPoliciesSize == 0) {
574
0
            UA_free(config->securityPolicies);
575
0
            config->securityPolicies = NULL;
576
0
        }
577
0
        return retval;
578
0
    }
579
580
13.5k
    config->securityPoliciesSize++;
581
13.5k
    return UA_STATUSCODE_GOOD;
582
13.5k
}
583
584
UA_EXPORT UA_StatusCode
585
UA_ServerConfig_addEndpoint(UA_ServerConfig *config, const UA_String securityPolicyUri,
586
13.5k
                            UA_MessageSecurityMode securityMode) {
587
    /* Lookup the security policy */
588
13.5k
    const UA_SecurityPolicy *policy = NULL;
589
13.5k
    for (size_t i = 0; i < config->securityPoliciesSize; ++i) {
590
13.5k
        if (UA_String_equal(&securityPolicyUri, &config->securityPolicies[i].policyUri)) {
591
13.5k
            policy = &config->securityPolicies[i];
592
13.5k
            break;
593
13.5k
        }
594
13.5k
    }
595
13.5k
    if(!policy)
596
0
        return UA_STATUSCODE_BADINVALIDARGUMENT;
597
598
    /* Populate the endpoint */
599
13.5k
    return addEndpoint(config, policy, securityMode);
600
13.5k
}
601
602
UA_EXPORT UA_StatusCode
603
0
UA_ServerConfig_addAllEndpoints(UA_ServerConfig *config) {
604
    /* Populate the endpoints */
605
0
    for(size_t i = 0; i < config->securityPoliciesSize; ++i) {
606
0
        if(UA_String_equal(&UA_SECURITY_POLICY_NONE_URI, &config->securityPolicies[i].policyUri)) {
607
0
            UA_StatusCode retval =
608
0
                addEndpoint(config, &config->securityPolicies[i], UA_MESSAGESECURITYMODE_NONE);
609
0
            if(retval != UA_STATUSCODE_GOOD)
610
0
                return retval;
611
0
        } else {
612
0
            UA_StatusCode retval =
613
0
                addEndpoint(config, &config->securityPolicies[i], UA_MESSAGESECURITYMODE_SIGN);
614
0
            if(retval != UA_STATUSCODE_GOOD)
615
0
                return retval;
616
0
            retval = addEndpoint(config, &config->securityPolicies[i],
617
0
                                 UA_MESSAGESECURITYMODE_SIGNANDENCRYPT);
618
0
            if(retval != UA_STATUSCODE_GOOD)
619
0
                return retval;
620
0
        }
621
0
    }
622
623
0
    return UA_STATUSCODE_GOOD;
624
0
}
625
626
UA_EXPORT UA_StatusCode
627
0
UA_ServerConfig_addAllSecureEndpoints(UA_ServerConfig *config) {
628
629
    /* Delete all predefined endpoints. */
630
0
    if(config->endpointsSize > 0) {
631
0
        for(size_t i = 0; i < config->endpointsSize; ++i)
632
0
            UA_EndpointDescription_clear(&config->endpoints[i]);
633
634
0
        UA_free(config->endpoints);
635
0
        config->endpoints = NULL;
636
0
        config->endpointsSize = 0;
637
0
    }
638
639
    /* Populate the endpoints */
640
0
    for(size_t i = 0; i < config->securityPoliciesSize; ++i) {
641
        /* Skip the None and all deprecated policies */
642
0
        if(config->securityPolicies[i].securityLevel == 0)
643
0
            continue;
644
0
        UA_StatusCode retval =
645
0
            addEndpoint(config, &config->securityPolicies[i], UA_MESSAGESECURITYMODE_SIGN);
646
0
        if(retval != UA_STATUSCODE_GOOD)
647
0
            return retval;
648
0
        retval = addEndpoint(config, &config->securityPolicies[i],
649
0
                             UA_MESSAGESECURITYMODE_SIGNANDENCRYPT);
650
0
        if(retval != UA_STATUSCODE_GOOD)
651
0
            return retval;
652
0
    }
653
654
0
    return UA_STATUSCODE_GOOD;
655
0
}
656
657
UA_EXPORT UA_StatusCode
658
UA_ServerConfig_setMinimalCustomBuffer(UA_ServerConfig *config, UA_UInt16 portNumber,
659
                                       const UA_ByteString *certificate,
660
                                       UA_UInt32 sendBufferSize,
661
13.5k
                                       UA_UInt32 recvBufferSize) {
662
13.5k
    if(!config)
663
0
        return UA_STATUSCODE_BADINVALIDARGUMENT;
664
665
13.5k
    UA_StatusCode retval = setDefaultConfig(config, portNumber);
666
13.5k
    if(retval != UA_STATUSCODE_GOOD) {
667
0
        UA_ServerConfig_clear(config);
668
0
        return retval;
669
0
    }
670
671
    /* Set the TCP settings. Only recvBufferSize is stored; it drives both
672
     * connConfig.recvBufferSize and connConfig.sendBufferSize. sendBufferSize is
673
     * intentionally ignored (see the doxygen note on the declaration). */
674
13.5k
    (void)sendBufferSize;
675
13.5k
    config->tcpBufSize = recvBufferSize;
676
677
    /* Allocate the SecurityPolicies */
678
13.5k
    retval = UA_ServerConfig_addSecurityPolicyNone(config, certificate);
679
13.5k
    if(retval != UA_STATUSCODE_GOOD) {
680
0
        UA_ServerConfig_clear(config);
681
0
        return retval;
682
0
    }
683
684
    /* Initialize the Access Control plugin */
685
13.5k
    retval = UA_AccessControl_default(config, true, NULL, 0, NULL);
686
13.5k
    if(retval != UA_STATUSCODE_GOOD) {
687
0
        UA_ServerConfig_clear(config);
688
0
        return retval;
689
0
    }
690
691
    /* Allocate the endpoint */
692
13.5k
    retval = UA_ServerConfig_addEndpoint(config, UA_SECURITY_POLICY_NONE_URI,
693
13.5k
                                         UA_MESSAGESECURITYMODE_NONE);
694
13.5k
    if(retval != UA_STATUSCODE_GOOD) {
695
0
        UA_ServerConfig_clear(config);
696
0
        return retval;
697
0
    }
698
699
13.5k
    return UA_STATUSCODE_GOOD;
700
13.5k
}
701
702
#ifdef UA_ENABLE_ENCRYPTION
703
704
UA_EXPORT UA_StatusCode
705
UA_ServerConfig_addSecurityPolicyBasic128Rsa15(UA_ServerConfig *config,
706
                                               const UA_ByteString *certificate,
707
0
                                               const UA_ByteString *privateKey) {
708
    /* Allocate the SecurityPolicies */
709
0
    UA_SecurityPolicy *tmp = (UA_SecurityPolicy *)
710
0
        UA_realloc(config->securityPolicies,
711
0
                   sizeof(UA_SecurityPolicy) * (1 + config->securityPoliciesSize));
712
0
    if(!tmp)
713
0
        return UA_STATUSCODE_BADOUTOFMEMORY;
714
0
    config->securityPolicies = tmp;
715
716
    /* Populate the SecurityPolicies */
717
0
    UA_ByteString localCertificate = UA_BYTESTRING_NULL;
718
0
    UA_ByteString localPrivateKey  = UA_BYTESTRING_NULL;
719
0
    if(certificate)
720
0
        localCertificate = *certificate;
721
0
    if(privateKey)
722
0
       localPrivateKey = *privateKey;
723
0
    UA_StatusCode retval =
724
0
        UA_SecurityPolicy_Basic128Rsa15(&config->securityPolicies[config->securityPoliciesSize],
725
0
                                        localCertificate, localPrivateKey, config->logging);
726
0
    if(retval != UA_STATUSCODE_GOOD) {
727
0
        if(config->securityPoliciesSize == 0) {
728
0
            UA_free(config->securityPolicies);
729
0
            config->securityPolicies = NULL;
730
0
        }
731
0
        return retval;
732
0
    }
733
734
0
    config->securityPoliciesSize++;
735
0
    return UA_STATUSCODE_GOOD;
736
0
}
737
738
UA_EXPORT UA_StatusCode
739
UA_ServerConfig_addSecurityPolicyBasic256(UA_ServerConfig *config,
740
                                          const UA_ByteString *certificate,
741
0
                                          const UA_ByteString *privateKey) {
742
    /* Allocate the SecurityPolicies */
743
0
    UA_SecurityPolicy *tmp = (UA_SecurityPolicy *)
744
0
        UA_realloc(config->securityPolicies,
745
0
                   sizeof(UA_SecurityPolicy) * (1 + config->securityPoliciesSize));
746
0
    if(!tmp)
747
0
        return UA_STATUSCODE_BADOUTOFMEMORY;
748
0
    config->securityPolicies = tmp;
749
750
    /* Populate the SecurityPolicies */
751
0
    UA_ByteString localCertificate = UA_BYTESTRING_NULL;
752
0
    UA_ByteString localPrivateKey  = UA_BYTESTRING_NULL;
753
0
    if(certificate)
754
0
        localCertificate = *certificate;
755
0
    if(privateKey)
756
0
       localPrivateKey = *privateKey;
757
0
    UA_StatusCode retval =
758
0
        UA_SecurityPolicy_Basic256(&config->securityPolicies[config->securityPoliciesSize],
759
0
                                   localCertificate, localPrivateKey, config->logging);
760
0
    if(retval != UA_STATUSCODE_GOOD) {
761
0
        if(config->securityPoliciesSize == 0) {
762
0
            UA_free(config->securityPolicies);
763
0
            config->securityPolicies = NULL;
764
0
        }
765
0
        return retval;
766
0
    }
767
768
0
    config->securityPoliciesSize++;
769
0
    return UA_STATUSCODE_GOOD;
770
0
}
771
772
UA_EXPORT UA_StatusCode
773
UA_ServerConfig_addSecurityPolicyBasic256Sha256(UA_ServerConfig *config,
774
                                                const UA_ByteString *certificate,
775
0
                                                const UA_ByteString *privateKey) {
776
    /* Allocate the SecurityPolicies */
777
0
    UA_SecurityPolicy *tmp = (UA_SecurityPolicy *)
778
0
        UA_realloc(config->securityPolicies,
779
0
                   sizeof(UA_SecurityPolicy) * (1 + config->securityPoliciesSize));
780
0
    if(!tmp)
781
0
        return UA_STATUSCODE_BADOUTOFMEMORY;
782
0
    config->securityPolicies = tmp;
783
784
    /* Populate the SecurityPolicies */
785
0
    UA_ByteString localCertificate = UA_BYTESTRING_NULL;
786
0
    UA_ByteString localPrivateKey  = UA_BYTESTRING_NULL;
787
0
    if(certificate)
788
0
        localCertificate = *certificate;
789
0
    if(privateKey)
790
0
       localPrivateKey = *privateKey;
791
0
    UA_StatusCode retval =
792
0
        UA_SecurityPolicy_Basic256Sha256(&config->securityPolicies[config->securityPoliciesSize],
793
0
                                         localCertificate, localPrivateKey, config->logging);
794
0
    if(retval != UA_STATUSCODE_GOOD) {
795
0
        if(config->securityPoliciesSize == 0) {
796
0
            UA_free(config->securityPolicies);
797
0
            config->securityPolicies = NULL;
798
0
        }
799
0
        return retval;
800
0
    }
801
802
0
    config->securityPoliciesSize++;
803
0
    return UA_STATUSCODE_GOOD;
804
0
}
805
806
UA_EXPORT UA_StatusCode
807
UA_ServerConfig_addSecurityPolicyAes128Sha256RsaOaep(UA_ServerConfig *config,
808
                                                const UA_ByteString *certificate,
809
0
                                                const UA_ByteString *privateKey) {
810
    /* Allocate the SecurityPolicies */
811
0
    UA_SecurityPolicy *tmp = (UA_SecurityPolicy *)
812
0
        UA_realloc(config->securityPolicies,
813
0
                   sizeof(UA_SecurityPolicy) * (1 + config->securityPoliciesSize));
814
0
    if(!tmp)
815
0
        return UA_STATUSCODE_BADOUTOFMEMORY;
816
0
    config->securityPolicies = tmp;
817
818
    /* Populate the SecurityPolicies */
819
0
    UA_ByteString localCertificate = UA_BYTESTRING_NULL;
820
0
    UA_ByteString localPrivateKey  = UA_BYTESTRING_NULL;
821
0
    if(certificate)
822
0
        localCertificate = *certificate;
823
0
    if(privateKey)
824
0
       localPrivateKey = *privateKey;
825
0
    UA_StatusCode retval =
826
0
        UA_SecurityPolicy_Aes128Sha256RsaOaep(&config->securityPolicies[config->securityPoliciesSize],
827
0
                                              localCertificate, localPrivateKey, config->logging);
828
0
    if(retval != UA_STATUSCODE_GOOD) {
829
0
        if(config->securityPoliciesSize == 0) {
830
0
            UA_free(config->securityPolicies);
831
0
            config->securityPolicies = NULL;
832
0
        }
833
0
        return retval;
834
0
    }
835
836
0
    config->securityPoliciesSize++;
837
0
    return UA_STATUSCODE_GOOD;
838
0
}
839
840
UA_EXPORT UA_StatusCode
841
UA_ServerConfig_addSecurityPolicyAes256Sha256RsaPss(UA_ServerConfig *config,
842
                                                     const UA_ByteString *certificate,
843
0
                                                     const UA_ByteString *privateKey) {
844
    /* Allocate the SecurityPolicies */
845
0
    UA_SecurityPolicy *tmp = (UA_SecurityPolicy *)
846
0
        UA_realloc(config->securityPolicies,
847
0
                   sizeof(UA_SecurityPolicy) * (1 + config->securityPoliciesSize));
848
0
    if(!tmp)
849
0
        return UA_STATUSCODE_BADOUTOFMEMORY;
850
0
    config->securityPolicies = tmp;
851
852
    /* Populate the SecurityPolicies */
853
0
    UA_ByteString localCertificate = UA_BYTESTRING_NULL;
854
0
    UA_ByteString localPrivateKey  = UA_BYTESTRING_NULL;
855
0
    if(certificate)
856
0
        localCertificate = *certificate;
857
0
    if(privateKey)
858
0
        localPrivateKey = *privateKey;
859
0
    UA_StatusCode retval =
860
0
        UA_SecurityPolicy_Aes256Sha256RsaPss(&config->securityPolicies[config->securityPoliciesSize],
861
0
                                              localCertificate, localPrivateKey, config->logging);
862
0
    if(retval != UA_STATUSCODE_GOOD) {
863
0
        if(config->securityPoliciesSize == 0) {
864
0
            UA_free(config->securityPolicies);
865
0
            config->securityPolicies = NULL;
866
0
        }
867
0
        return retval;
868
0
    }
869
870
0
    config->securityPoliciesSize++;
871
0
    return UA_STATUSCODE_GOOD;
872
0
}
873
874
#if defined(UA_ENABLE_ENCRYPTION_OPENSSL) || \
875
    (defined(UA_ENABLE_ENCRYPTION_MBEDTLS) && MBEDTLS_VERSION_NUMBER >= 0x03000000)
876
UA_EXPORT UA_StatusCode
877
UA_ServerConfig_addSecurityPolicyEccNistP256(UA_ServerConfig *config,
878
                                                     const UA_ByteString *certificate,
879
                                                     const UA_ByteString *privateKey) {
880
    /* Allocate the SecurityPolicies */
881
    UA_SecurityPolicy *tmp = (UA_SecurityPolicy *)
882
        UA_realloc(config->securityPolicies,
883
                   sizeof(UA_SecurityPolicy) * (1 + config->securityPoliciesSize));
884
    if(!tmp)
885
        return UA_STATUSCODE_BADOUTOFMEMORY;
886
    config->securityPolicies = tmp;
887
888
    /* Populate the SecurityPolicies */
889
    UA_ByteString localCertificate = UA_BYTESTRING_NULL;
890
    UA_ByteString localPrivateKey  = UA_BYTESTRING_NULL;
891
    if(certificate)
892
        localCertificate = *certificate;
893
    if(privateKey)
894
        localPrivateKey = *privateKey;
895
    UA_StatusCode retval =
896
        UA_SecurityPolicy_EccNistP256(&config->securityPolicies[config->securityPoliciesSize],
897
                                              UA_APPLICATIONTYPE_SERVER, localCertificate,
898
                                              localPrivateKey, config->logging);
899
    if(retval != UA_STATUSCODE_GOOD) {
900
        if(config->securityPoliciesSize == 0) {
901
            UA_free(config->securityPolicies);
902
            config->securityPolicies = NULL;
903
        }
904
        return retval;
905
    }
906
907
    config->securityPoliciesSize++;
908
    return UA_STATUSCODE_GOOD;
909
}
910
911
/* The AEAD ECC policies (AesGcm / ChaChaPoly) are only implemented in the
912
 * OpenSSL backend; their constructors do not exist for mbedTLS. */
913
#if defined(UA_ENABLE_ENCRYPTION_OPENSSL)
914
UA_EXPORT UA_StatusCode
915
UA_ServerConfig_addSecurityPolicyEccNistP256AesGcm(UA_ServerConfig *config,
916
                                                    const UA_ByteString *certificate,
917
                                                    const UA_ByteString *privateKey) {
918
    /* Allocate the SecurityPolicies */
919
    UA_SecurityPolicy *tmp = (UA_SecurityPolicy *)
920
        UA_realloc(config->securityPolicies,
921
                   sizeof(UA_SecurityPolicy) * (1 + config->securityPoliciesSize));
922
    if(!tmp)
923
        return UA_STATUSCODE_BADOUTOFMEMORY;
924
    config->securityPolicies = tmp;
925
926
    /* Populate the SecurityPolicies */
927
    UA_ByteString localCertificate = UA_BYTESTRING_NULL;
928
    UA_ByteString localPrivateKey  = UA_BYTESTRING_NULL;
929
    if(certificate)
930
        localCertificate = *certificate;
931
    if(privateKey)
932
        localPrivateKey = *privateKey;
933
    UA_StatusCode retval =
934
        UA_SecurityPolicy_EccNistP256AesGcm(&config->securityPolicies[config->securityPoliciesSize],
935
                                              UA_APPLICATIONTYPE_SERVER, localCertificate,
936
                                              localPrivateKey, config->logging);
937
    if(retval != UA_STATUSCODE_GOOD) {
938
        if(config->securityPoliciesSize == 0) {
939
            UA_free(config->securityPolicies);
940
            config->securityPolicies = NULL;
941
        }
942
        return retval;
943
    }
944
945
    config->securityPoliciesSize++;
946
    return UA_STATUSCODE_GOOD;
947
}
948
949
UA_EXPORT UA_StatusCode
950
UA_ServerConfig_addSecurityPolicyEccNistP256ChaChaPoly(UA_ServerConfig *config,
951
                                                       const UA_ByteString *certificate,
952
                                                       const UA_ByteString *privateKey) {
953
    /* Allocate the SecurityPolicies */
954
    UA_SecurityPolicy *tmp = (UA_SecurityPolicy *)
955
        UA_realloc(config->securityPolicies,
956
                   sizeof(UA_SecurityPolicy) * (1 + config->securityPoliciesSize));
957
    if(!tmp)
958
        return UA_STATUSCODE_BADOUTOFMEMORY;
959
    config->securityPolicies = tmp;
960
961
    /* Populate the SecurityPolicies */
962
    UA_ByteString localCertificate = UA_BYTESTRING_NULL;
963
    UA_ByteString localPrivateKey  = UA_BYTESTRING_NULL;
964
    if(certificate)
965
        localCertificate = *certificate;
966
    if(privateKey)
967
        localPrivateKey = *privateKey;
968
    UA_StatusCode retval =
969
        UA_SecurityPolicy_EccNistP256ChaChaPoly(&config->securityPolicies[config->securityPoliciesSize],
970
                                                UA_APPLICATIONTYPE_SERVER, localCertificate,
971
                                                localPrivateKey, config->logging);
972
    if(retval != UA_STATUSCODE_GOOD) {
973
        if(config->securityPoliciesSize == 0) {
974
            UA_free(config->securityPolicies);
975
            config->securityPolicies = NULL;
976
        }
977
        return retval;
978
    }
979
980
    config->securityPoliciesSize++;
981
    return UA_STATUSCODE_GOOD;
982
}
983
#endif /* UA_ENABLE_ENCRYPTION_OPENSSL (AEAD ECC policies) */
984
985
UA_EXPORT UA_StatusCode
986
UA_ServerConfig_addSecurityPolicyEccNistP384(UA_ServerConfig *config,
987
                                             const UA_ByteString *certificate,
988
                                             const UA_ByteString *privateKey) {
989
    UA_SecurityPolicy *tmp = (UA_SecurityPolicy *)
990
        UA_realloc(config->securityPolicies,
991
                   sizeof(UA_SecurityPolicy) * (1 + config->securityPoliciesSize));
992
    if(!tmp)
993
        return UA_STATUSCODE_BADOUTOFMEMORY;
994
    config->securityPolicies = tmp;
995
996
    UA_ByteString localCertificate = UA_BYTESTRING_NULL;
997
    UA_ByteString localPrivateKey  = UA_BYTESTRING_NULL;
998
    if(certificate)
999
        localCertificate = *certificate;
1000
    if(privateKey)
1001
        localPrivateKey = *privateKey;
1002
    UA_StatusCode retval =
1003
        UA_SecurityPolicy_EccNistP384(&config->securityPolicies[config->securityPoliciesSize],
1004
                                      UA_APPLICATIONTYPE_SERVER, localCertificate,
1005
                                      localPrivateKey, config->logging);
1006
    if(retval != UA_STATUSCODE_GOOD) {
1007
        if(config->securityPoliciesSize == 0) {
1008
            UA_free(config->securityPolicies);
1009
            config->securityPolicies = NULL;
1010
        }
1011
        return retval;
1012
    }
1013
1014
    config->securityPoliciesSize++;
1015
    return UA_STATUSCODE_GOOD;
1016
}
1017
UA_EXPORT UA_StatusCode
1018
UA_ServerConfig_addSecurityPolicyEccBrainpoolP256r1(UA_ServerConfig *config,
1019
                                                    const UA_ByteString *certificate,
1020
                                                    const UA_ByteString *privateKey) {
1021
    UA_SecurityPolicy *tmp = (UA_SecurityPolicy *)
1022
        UA_realloc(config->securityPolicies,
1023
                   sizeof(UA_SecurityPolicy) * (1 + config->securityPoliciesSize));
1024
    if(!tmp)
1025
        return UA_STATUSCODE_BADOUTOFMEMORY;
1026
    config->securityPolicies = tmp;
1027
1028
    UA_ByteString localCertificate = UA_BYTESTRING_NULL;
1029
    UA_ByteString localPrivateKey  = UA_BYTESTRING_NULL;
1030
    if(certificate)
1031
        localCertificate = *certificate;
1032
    if(privateKey)
1033
        localPrivateKey = *privateKey;
1034
    UA_StatusCode retval =
1035
        UA_SecurityPolicy_EccBrainpoolP256r1(&config->securityPolicies[config->securityPoliciesSize],
1036
                                             UA_APPLICATIONTYPE_SERVER, localCertificate,
1037
                                             localPrivateKey, config->logging);
1038
    if(retval != UA_STATUSCODE_GOOD) {
1039
        if(config->securityPoliciesSize == 0) {
1040
            UA_free(config->securityPolicies);
1041
            config->securityPolicies = NULL;
1042
        }
1043
        return retval;
1044
    }
1045
1046
    config->securityPoliciesSize++;
1047
    return UA_STATUSCODE_GOOD;
1048
}
1049
UA_EXPORT UA_StatusCode
1050
UA_ServerConfig_addSecurityPolicyEccBrainpoolP384r1(UA_ServerConfig *config,
1051
                                                    const UA_ByteString *certificate,
1052
                                                    const UA_ByteString *privateKey) {
1053
    UA_SecurityPolicy *tmp = (UA_SecurityPolicy *)
1054
        UA_realloc(config->securityPolicies,
1055
                   sizeof(UA_SecurityPolicy) * (1 + config->securityPoliciesSize));
1056
    if(!tmp)
1057
        return UA_STATUSCODE_BADOUTOFMEMORY;
1058
    config->securityPolicies = tmp;
1059
1060
    UA_ByteString localCertificate = UA_BYTESTRING_NULL;
1061
    UA_ByteString localPrivateKey  = UA_BYTESTRING_NULL;
1062
    if(certificate)
1063
        localCertificate = *certificate;
1064
    if(privateKey)
1065
        localPrivateKey = *privateKey;
1066
    UA_StatusCode retval =
1067
        UA_SecurityPolicy_EccBrainpoolP384r1(&config->securityPolicies[config->securityPoliciesSize],
1068
                                             UA_APPLICATIONTYPE_SERVER, localCertificate,
1069
                                             localPrivateKey, config->logging);
1070
    if(retval != UA_STATUSCODE_GOOD) {
1071
        if(config->securityPoliciesSize == 0) {
1072
            UA_free(config->securityPolicies);
1073
            config->securityPolicies = NULL;
1074
        }
1075
        return retval;
1076
    }
1077
1078
    config->securityPoliciesSize++;
1079
    return UA_STATUSCODE_GOOD;
1080
}
1081
#endif /* UA_ENABLE_ENCRYPTION_OPENSSL || mbedTLS ECC */
1082
1083
#if defined(UA_ENABLE_ENCRYPTION_OPENSSL)
1084
UA_EXPORT UA_StatusCode
1085
UA_ServerConfig_addSecurityPolicyEccCurve25519(UA_ServerConfig *config,
1086
                                               const UA_ByteString *certificate,
1087
                                               const UA_ByteString *privateKey) {
1088
    UA_SecurityPolicy *tmp = (UA_SecurityPolicy *)
1089
        UA_realloc(config->securityPolicies,
1090
                   sizeof(UA_SecurityPolicy) * (1 + config->securityPoliciesSize));
1091
    if(!tmp)
1092
        return UA_STATUSCODE_BADOUTOFMEMORY;
1093
    config->securityPolicies = tmp;
1094
1095
    UA_ByteString localCertificate = UA_BYTESTRING_NULL;
1096
    UA_ByteString localPrivateKey  = UA_BYTESTRING_NULL;
1097
    if(certificate)
1098
        localCertificate = *certificate;
1099
    if(privateKey)
1100
        localPrivateKey = *privateKey;
1101
    UA_StatusCode retval =
1102
        UA_SecurityPolicy_EccCurve25519(&config->securityPolicies[config->securityPoliciesSize],
1103
                                        UA_APPLICATIONTYPE_SERVER, localCertificate,
1104
                                        localPrivateKey, config->logging);
1105
    if(retval != UA_STATUSCODE_GOOD) {
1106
        if(config->securityPoliciesSize == 0) {
1107
            UA_free(config->securityPolicies);
1108
            config->securityPolicies = NULL;
1109
        }
1110
        return retval;
1111
    }
1112
1113
    config->securityPoliciesSize++;
1114
    return UA_STATUSCODE_GOOD;
1115
}
1116
UA_EXPORT UA_StatusCode
1117
UA_ServerConfig_addSecurityPolicyEccCurve448(UA_ServerConfig *config,
1118
                                             const UA_ByteString *certificate,
1119
                                             const UA_ByteString *privateKey) {
1120
    UA_SecurityPolicy *tmp = (UA_SecurityPolicy *)
1121
        UA_realloc(config->securityPolicies,
1122
                   sizeof(UA_SecurityPolicy) * (1 + config->securityPoliciesSize));
1123
    if(!tmp)
1124
        return UA_STATUSCODE_BADOUTOFMEMORY;
1125
    config->securityPolicies = tmp;
1126
1127
    UA_ByteString localCertificate = UA_BYTESTRING_NULL;
1128
    UA_ByteString localPrivateKey  = UA_BYTESTRING_NULL;
1129
    if(certificate)
1130
        localCertificate = *certificate;
1131
    if(privateKey)
1132
        localPrivateKey = *privateKey;
1133
    UA_StatusCode retval =
1134
        UA_SecurityPolicy_EccCurve448(&config->securityPolicies[config->securityPoliciesSize],
1135
                                      UA_APPLICATIONTYPE_SERVER, localCertificate,
1136
                                      localPrivateKey, config->logging);
1137
    if(retval != UA_STATUSCODE_GOOD) {
1138
        if(config->securityPoliciesSize == 0) {
1139
            UA_free(config->securityPolicies);
1140
            config->securityPolicies = NULL;
1141
        }
1142
        return retval;
1143
    }
1144
1145
    config->securityPoliciesSize++;
1146
    return UA_STATUSCODE_GOOD;
1147
}
1148
#endif
1149
1150
1151
/* This assumes that the sp array has enough space for up to SECURITY_POLICY_SIZE policies.
1152
 * Policies that have been added are not cleaned up after an error.
1153
 * Certificate and/or pricateKey can be NULL and will not be used then.
1154
 * Logs a warning if policies could not be added. */
1155
static void
1156
addAllSecurityPolicies(UA_SecurityPolicy *sp, size_t *length,
1157
                       const UA_ByteString certificate, const UA_ByteString privateKey,
1158
                       UA_Boolean onlySecure, UA_ApplicationType applicationType,
1159
0
                       UA_Logger *logging) {
1160
    /* Basic256Sha256 */
1161
0
    UA_StatusCode retval = UA_SecurityPolicy_Basic256Sha256(sp + *length, certificate, privateKey, logging);
1162
0
    *length += (retval == UA_STATUSCODE_GOOD) ? 1 : 0;
1163
0
    if(retval != UA_STATUSCODE_GOOD) {
1164
0
        UA_LOG_WARNING(logging, UA_LOGCATEGORY_APPLICATION,
1165
0
                       "Could not add SecurityPolicy#Basic256Sha256 with error code %s",
1166
0
                       UA_StatusCode_name(retval));
1167
0
    }
1168
1169
    /* Aes256Sha256RsaPss */
1170
0
    retval = UA_SecurityPolicy_Aes256Sha256RsaPss(sp + *length, certificate, privateKey, logging);
1171
0
    *length += (retval == UA_STATUSCODE_GOOD) ? 1 : 0;
1172
0
    if(retval != UA_STATUSCODE_GOOD) {
1173
0
        UA_LOG_WARNING(logging, UA_LOGCATEGORY_APPLICATION,
1174
0
                       "Could not add SecurityPolicy#Aes256Sha256RsaPss with error code %s",
1175
0
                       UA_StatusCode_name(retval));
1176
0
    }
1177
1178
    /* Aes128Sha256RsaOaep */
1179
0
    retval = UA_SecurityPolicy_Aes128Sha256RsaOaep(sp + *length, certificate, privateKey, logging);
1180
0
    *length += (retval == UA_STATUSCODE_GOOD) ? 1 : 0;
1181
0
    if(retval != UA_STATUSCODE_GOOD) {
1182
0
        UA_LOG_WARNING(logging, UA_LOGCATEGORY_APPLICATION,
1183
0
                       "Could not add SecurityPolicy#Aes128Sha256RsaOaep with error code %s",
1184
0
                       UA_StatusCode_name(retval));
1185
0
    }
1186
1187
    /* The non-deprecated ECC SecurityPolicies are the AEAD profiles, which are
1188
     * implemented only in the OpenSSL backend. The deprecated non-AEAD ECC
1189
     * policies (EccNistP256/P384, EccBrainpoolP256r1/P384r1) are not part of the
1190
     * default set; add them explicitly via UA_ServerConfig_addSecurityPolicyEcc*. */
1191
#if defined(UA_ENABLE_ENCRYPTION_OPENSSL)
1192
    /* EccNistP256AesGcm */
1193
    retval = UA_SecurityPolicy_EccNistP256AesGcm(sp + *length, applicationType,
1194
                                                  certificate, privateKey, logging);
1195
    *length += (retval == UA_STATUSCODE_GOOD) ? 1 : 0;
1196
    if(retval != UA_STATUSCODE_GOOD) {
1197
        UA_LOG_WARNING(logging, UA_LOGCATEGORY_APPLICATION,
1198
                       "Could not add SecurityPolicy#EccNistP256_AesGcm with error code %s",
1199
                       UA_StatusCode_name(retval));
1200
    }
1201
1202
    /* EccNistP256ChaChaPoly */
1203
    retval = UA_SecurityPolicy_EccNistP256ChaChaPoly(sp + *length, applicationType,
1204
                                                     certificate, privateKey, logging);
1205
    *length += (retval == UA_STATUSCODE_GOOD) ? 1 : 0;
1206
    if(retval != UA_STATUSCODE_GOOD) {
1207
        UA_LOG_WARNING(logging, UA_LOGCATEGORY_APPLICATION,
1208
                       "Could not add SecurityPolicy#EccNistP256_ChaChaPoly with error code %s",
1209
                       UA_StatusCode_name(retval));
1210
    }
1211
1212
    /* EccCurve25519 */
1213
    retval = UA_SecurityPolicy_EccCurve25519(sp + *length, applicationType,
1214
                                             certificate, privateKey, logging);
1215
    *length += (retval == UA_STATUSCODE_GOOD) ? 1 : 0;
1216
    if(retval != UA_STATUSCODE_GOOD) {
1217
        UA_LOG_WARNING(logging, UA_LOGCATEGORY_APPLICATION,
1218
                       "Could not add SecurityPolicy#EccCurve25519 with error code %s",
1219
                       UA_StatusCode_name(retval));
1220
    }
1221
1222
    /* EccCurve448 */
1223
    retval = UA_SecurityPolicy_EccCurve448(sp + *length, applicationType,
1224
                                           certificate, privateKey, logging);
1225
    *length += (retval == UA_STATUSCODE_GOOD) ? 1 : 0;
1226
    if(retval != UA_STATUSCODE_GOOD) {
1227
        UA_LOG_WARNING(logging, UA_LOGCATEGORY_APPLICATION,
1228
                       "Could not add SecurityPolicy#EccCurve448 with error code %s",
1229
                       UA_StatusCode_name(retval));
1230
    }
1231
#endif
1232
1233
    /* Don't add "unsecure" SecurityPolicies */
1234
0
    if(onlySecure)
1235
0
        return;
1236
1237
    /* None */
1238
0
    retval = UA_SecurityPolicy_None(sp + *length, certificate, logging);
1239
0
    *length += (retval == UA_STATUSCODE_GOOD) ? 1 : 0;
1240
0
    if(retval != UA_STATUSCODE_GOOD) {
1241
0
        UA_LOG_WARNING(logging, UA_LOGCATEGORY_APPLICATION,
1242
0
                       "Could not add SecurityPolicy#None with error code %s",
1243
0
                       UA_StatusCode_name(retval));
1244
0
    }
1245
1246
#ifdef UA_INCLUDE_INSECURE_POLICIES
1247
    /* Basic128Rsa15 should no longer be used */
1248
    retval = UA_SecurityPolicy_Basic128Rsa15(sp + *length, certificate, privateKey, logging);
1249
    *length += (retval == UA_STATUSCODE_GOOD) ? 1 : 0;
1250
    if(retval != UA_STATUSCODE_GOOD) {
1251
        UA_LOG_WARNING(logging, UA_LOGCATEGORY_APPLICATION,
1252
                       "Could not add SecurityPolicy#Basic128Rsa15 with error code %s",
1253
                       UA_StatusCode_name(retval));
1254
    }
1255
1256
    /* Basic256 should no longer be used */
1257
    retval = UA_SecurityPolicy_Basic256(sp + *length, certificate, privateKey, logging);
1258
    *length += (retval == UA_STATUSCODE_GOOD) ? 1 : 0;
1259
    if(retval != UA_STATUSCODE_GOOD) {
1260
        UA_LOG_WARNING(logging, UA_LOGCATEGORY_APPLICATION,
1261
                       "Could not add SecurityPolicy#Basic256 with error code %s",
1262
                       UA_StatusCode_name(retval));
1263
    }
1264
#endif
1265
1266
    /* The non-AEAD ECC SecurityPolicies (EccNistP256/P384,
1267
     * EccBrainpoolP256r1/P384r1) are deprecated (OPC UA Part 7), superseded by
1268
     * their *_AesGcm / *_ChaChaPoly variants. They are not part of the default
1269
     * policy set; use the UA_ServerConfig_addSecurityPolicyEcc* functions to add
1270
     * them explicitly. */
1271
0
}
1272
1273
static UA_StatusCode
1274
addAllServerSecurityPolicies(UA_ServerConfig *config,
1275
                             const UA_ByteString *certificate, const UA_ByteString *privateKey,
1276
0
                             UA_Boolean onlySecure) {
1277
    /* Populate the cert variables */
1278
0
    UA_ByteString localCertificate = UA_BYTESTRING_NULL;
1279
0
    UA_ByteString localPrivateKey  = UA_BYTESTRING_NULL;
1280
0
    if(certificate)
1281
0
        localCertificate = *certificate;
1282
0
    if(privateKey)
1283
0
       localPrivateKey = *privateKey;
1284
1285
    /* Load the private key and convert to the DER format. Use an empty password
1286
     * on the first try -- maybe the key does not require a password. */
1287
0
    UA_ByteString decryptedPrivateKey = UA_BYTESTRING_NULL;
1288
0
    UA_ByteString keyPassword = UA_BYTESTRING_NULL;
1289
0
    UA_StatusCode keySuccess = UA_STATUSCODE_GOOD;
1290
0
    if(privateKey && privateKey->length > 0)
1291
0
        keySuccess = UA_CertificateUtils_decryptPrivateKey(localPrivateKey, keyPassword,
1292
0
                                                           &decryptedPrivateKey);
1293
1294
    /* Get the password and decrypt. An application might want to loop / retry
1295
     * here to allow users to correct their entry. */
1296
0
    if(keySuccess != UA_STATUSCODE_GOOD) {
1297
0
        if(config->privateKeyPasswordCallback)
1298
0
            keySuccess = config->privateKeyPasswordCallback(config, &keyPassword);
1299
0
        else
1300
0
            keySuccess = readPrivateKeyPassword(&keyPassword);
1301
0
        if(keySuccess != UA_STATUSCODE_GOOD)
1302
0
            return keySuccess;
1303
0
        keySuccess = UA_CertificateUtils_decryptPrivateKey(localPrivateKey, keyPassword,
1304
0
                                                           &decryptedPrivateKey);
1305
0
        UA_ByteString_memZero(&keyPassword);
1306
0
        UA_ByteString_clear(&keyPassword);
1307
0
    }
1308
0
    if(keySuccess != UA_STATUSCODE_GOOD) {
1309
0
        UA_LOG_ERROR(config->logging, UA_LOGCATEGORY_APPLICATION,
1310
0
                     "Could not decrypt the private key with status code %s",
1311
0
                     UA_StatusCode_name(keySuccess));
1312
0
        return keySuccess;
1313
0
    }
1314
1315
    /* Clear up the old SecurityPolicies */
1316
0
    for(size_t i = 0; i < config->securityPoliciesSize; i++) {
1317
0
        config->securityPolicies[i].clear(&config->securityPolicies[i]);
1318
0
    }
1319
1320
    /* Allocate memory for the additional policies */
1321
0
    UA_SecurityPolicy *tmp = (UA_SecurityPolicy*)
1322
0
        UA_realloc(config->securityPolicies, sizeof(UA_SecurityPolicy) * SECURITY_POLICY_SIZE);
1323
0
    if(!tmp) {
1324
0
        UA_ByteString_memZero(&decryptedPrivateKey);
1325
0
        UA_ByteString_clear(&decryptedPrivateKey);
1326
0
        return UA_STATUSCODE_BADOUTOFMEMORY;
1327
0
    }
1328
1329
0
    config->securityPolicies = tmp;
1330
0
    config->securityPoliciesSize = 0;
1331
1332
    /* Do the generic addition of certificates */
1333
0
    addAllSecurityPolicies(config->securityPolicies, &config->securityPoliciesSize,
1334
0
                           localCertificate, decryptedPrivateKey, onlySecure,
1335
0
                           UA_APPLICATIONTYPE_SERVER, config->logging);
1336
1337
0
    if(config->securityPoliciesSize == 0) {
1338
0
        UA_free(config->securityPolicies);
1339
0
        config->securityPolicies = NULL;
1340
0
    }
1341
1342
0
    UA_ByteString_memZero(&decryptedPrivateKey);
1343
0
    UA_ByteString_clear(&decryptedPrivateKey);
1344
0
    return UA_STATUSCODE_GOOD;
1345
0
}
1346
1347
UA_StatusCode
1348
UA_ServerConfig_addAllSecurityPolicies(UA_ServerConfig *config,
1349
                                       const UA_ByteString *certificate,
1350
0
                                       const UA_ByteString *privateKey) {
1351
0
    return addAllServerSecurityPolicies(config, certificate, privateKey, false);
1352
0
}
1353
1354
/* Always returns UA_STATUSCODE_GOOD. Logs a warning if policies could not be added. */
1355
UA_StatusCode
1356
UA_ServerConfig_addAllSecureSecurityPolicies(UA_ServerConfig *config,
1357
                                             const UA_ByteString *certificate,
1358
0
                                             const UA_ByteString *privateKey) {
1359
0
    return addAllServerSecurityPolicies(config, certificate, privateKey, true);
1360
0
}
1361
1362
UA_EXPORT UA_StatusCode
1363
UA_ServerConfig_setDefaultWithSecurityPolicies(UA_ServerConfig *conf,
1364
                                               UA_UInt16 portNumber,
1365
                                               const UA_ByteString *certificate,
1366
                                               const UA_ByteString *privateKey,
1367
                                               const UA_ByteString *trustList,
1368
                                               size_t trustListSize,
1369
                                               const UA_ByteString *issuerList,
1370
                                               size_t issuerListSize,
1371
                                               const UA_ByteString *revocationList,
1372
0
                                               size_t revocationListSize) {
1373
0
    UA_StatusCode retval = setDefaultConfig(conf, portNumber);
1374
0
    if(retval != UA_STATUSCODE_GOOD) {
1375
0
        UA_ServerConfig_clear(conf);
1376
0
        return retval;
1377
0
    }
1378
1379
0
    if(trustListSize > 0) {
1380
0
        UA_TrustListDataType list;
1381
0
        UA_TrustListDataType_init(&list);
1382
0
        list.specifiedLists |= UA_TRUSTLISTMASKS_TRUSTEDCERTIFICATES;
1383
0
        retval = UA_Array_copy(trustList, trustListSize,
1384
0
                               (void**)&list.trustedCertificates,
1385
0
                               &UA_TYPES[UA_TYPES_BYTESTRING]);
1386
0
        if(retval != UA_STATUSCODE_GOOD)
1387
0
            return retval;
1388
0
        list.trustedCertificatesSize = trustListSize;
1389
1390
0
        if(issuerListSize > 0) {
1391
0
            list.specifiedLists |= UA_TRUSTLISTMASKS_ISSUERCERTIFICATES;
1392
0
            retval = UA_Array_copy(issuerList, issuerListSize,
1393
0
                                   (void**)&list.issuerCertificates,
1394
0
                                   &UA_TYPES[UA_TYPES_BYTESTRING]);
1395
0
            if(retval != UA_STATUSCODE_GOOD) {
1396
0
                UA_TrustListDataType_clear(&list);
1397
0
                return retval;
1398
0
            }
1399
0
            list.issuerCertificatesSize = issuerListSize;
1400
0
        }
1401
1402
0
        if(revocationListSize > 0) {
1403
0
            list.specifiedLists |= UA_TRUSTLISTMASKS_TRUSTEDCRLS;
1404
0
            retval = UA_Array_copy(revocationList, revocationListSize,
1405
0
                                   (void**)&list.trustedCrls,
1406
0
                                   &UA_TYPES[UA_TYPES_BYTESTRING]);
1407
0
            if(retval != UA_STATUSCODE_GOOD) {
1408
0
                UA_TrustListDataType_clear(&list);
1409
0
                return retval;
1410
0
            }
1411
0
            list.trustedCrlsSize = revocationListSize;
1412
0
        }
1413
1414
        /* Set up the parameters */
1415
0
        UA_KeyValuePair params[2];
1416
0
        size_t paramsSize = 2;
1417
1418
0
        params[0].key = UA_QUALIFIEDNAME(0, "max-trust-listsize");
1419
0
        UA_Variant_setScalar(&params[0].value, &conf->maxTrustListSize,
1420
0
                             &UA_TYPES[UA_TYPES_UINT32]);
1421
0
        params[1].key = UA_QUALIFIEDNAME(0, "max-rejected-listsize");
1422
0
        UA_Variant_setScalar(&params[1].value, &conf->maxRejectedListSize,
1423
0
                             &UA_TYPES[UA_TYPES_UINT32]);
1424
1425
0
        UA_KeyValueMap paramsMap;
1426
0
        paramsMap.map = params;
1427
0
        paramsMap.mapSize = paramsSize;
1428
1429
0
        UA_NodeId defaultApplicationGroup =
1430
0
            UA_NS0ID(SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP);
1431
0
        retval = UA_CertificateGroup_Memorystore(&conf->secureChannelPKI,
1432
0
                                                 &defaultApplicationGroup, &list,
1433
0
                                                 conf->logging, &paramsMap);
1434
0
        if(retval != UA_STATUSCODE_GOOD) {
1435
0
            UA_TrustListDataType_clear(&list);
1436
0
            return retval;
1437
0
        }
1438
1439
0
        UA_NodeId defaultUserTokenGroup =
1440
0
            UA_NS0ID(SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP);
1441
0
        retval = UA_CertificateGroup_Memorystore(&conf->sessionPKI,
1442
0
                                                 &defaultUserTokenGroup, &list,
1443
0
                                                 conf->logging, &paramsMap);
1444
0
        UA_TrustListDataType_clear(&list);
1445
0
        if(retval != UA_STATUSCODE_GOOD)
1446
0
            return retval;
1447
0
    } else {
1448
0
        UA_LOG_WARNING(conf->logging, UA_LOGCATEGORY_APPLICATION,
1449
0
                       "Empty trustlist passed. Leaving the previously "
1450
0
                       "configured certificate verification in place");
1451
0
    }
1452
1453
0
    retval = UA_ServerConfig_addAllSecurityPolicies(conf, certificate, privateKey);
1454
1455
    /* Reinitialize AccessControl to take the changed SecurityPolicies into account
1456
     * TODO: This looses username/pw during the reinitialization */
1457
0
    if(retval == UA_STATUSCODE_GOOD)
1458
0
        retval = UA_AccessControl_default(conf, true, NULL, 0, NULL);
1459
1460
0
    if(retval != UA_STATUSCODE_GOOD) {
1461
0
        UA_ServerConfig_clear(conf);
1462
0
        return retval;
1463
0
    }
1464
1465
0
    retval = UA_ServerConfig_addAllEndpoints(conf);
1466
0
    if(retval != UA_STATUSCODE_GOOD) {
1467
0
        UA_ServerConfig_clear(conf);
1468
0
        return retval;
1469
0
    }
1470
1471
0
    return UA_STATUSCODE_GOOD;
1472
0
}
1473
1474
UA_EXPORT UA_StatusCode
1475
UA_ServerConfig_setDefaultWithSecureSecurityPolicies(UA_ServerConfig *conf,
1476
                                               UA_UInt16 portNumber,
1477
                                               const UA_ByteString *certificate,
1478
                                               const UA_ByteString *privateKey,
1479
                                               const UA_ByteString *trustList,
1480
                                               size_t trustListSize,
1481
                                               const UA_ByteString *issuerList,
1482
                                               size_t issuerListSize,
1483
                                               const UA_ByteString *revocationList,
1484
0
                                               size_t revocationListSize) {
1485
0
    UA_StatusCode retval = setDefaultConfig(conf, portNumber);
1486
0
    if(retval != UA_STATUSCODE_GOOD) {
1487
0
        UA_ServerConfig_clear(conf);
1488
0
        return retval;
1489
0
    }
1490
1491
0
    if(trustListSize > 0) {
1492
0
        UA_TrustListDataType list;
1493
0
        UA_TrustListDataType_init(&list);
1494
0
        list.specifiedLists |= UA_TRUSTLISTMASKS_TRUSTEDCERTIFICATES;
1495
0
        retval = UA_Array_copy(trustList, trustListSize,
1496
0
                               (void**)&list.trustedCertificates,
1497
0
                               &UA_TYPES[UA_TYPES_BYTESTRING]);
1498
0
        if(retval != UA_STATUSCODE_GOOD)
1499
0
            return retval;
1500
0
        list.trustedCertificatesSize = trustListSize;
1501
1502
0
        if(issuerListSize > 0) {
1503
0
            list.specifiedLists |= UA_TRUSTLISTMASKS_ISSUERCERTIFICATES;
1504
0
            retval = UA_Array_copy(issuerList, issuerListSize,
1505
0
                                   (void**)&list.issuerCertificates,
1506
0
                                   &UA_TYPES[UA_TYPES_BYTESTRING]);
1507
0
            if(retval != UA_STATUSCODE_GOOD) {
1508
0
                UA_TrustListDataType_clear(&list);
1509
0
                return retval;
1510
0
            }
1511
0
            list.issuerCertificatesSize = issuerListSize;
1512
0
        }
1513
1514
0
        if(revocationListSize > 0) {
1515
0
            list.specifiedLists |= UA_TRUSTLISTMASKS_TRUSTEDCRLS;
1516
0
            retval = UA_Array_copy(revocationList, revocationListSize,
1517
0
                                   (void**)&list.trustedCrls,
1518
0
                                   &UA_TYPES[UA_TYPES_BYTESTRING]);
1519
0
            if(retval != UA_STATUSCODE_GOOD) {
1520
0
                UA_TrustListDataType_clear(&list);
1521
0
                return retval;
1522
0
            }
1523
0
            list.trustedCrlsSize = revocationListSize;
1524
0
        }
1525
1526
        /* Set up the parameters */
1527
0
        UA_KeyValuePair params[2];
1528
0
        size_t paramsSize = 2;
1529
1530
0
        params[0].key = UA_QUALIFIEDNAME(0, "max-trust-listsize");
1531
0
        UA_Variant_setScalar(&params[0].value, &conf->maxTrustListSize, &UA_TYPES[UA_TYPES_UINT32]);
1532
0
        params[1].key = UA_QUALIFIEDNAME(0, "max-rejected-listsize");
1533
0
        UA_Variant_setScalar(&params[1].value, &conf->maxRejectedListSize, &UA_TYPES[UA_TYPES_UINT32]);
1534
1535
0
        UA_KeyValueMap paramsMap;
1536
0
        paramsMap.map = params;
1537
0
        paramsMap.mapSize = paramsSize;
1538
1539
0
        UA_NodeId defaultApplicationGroup =
1540
0
            UA_NS0ID(SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP);
1541
0
        retval = UA_CertificateGroup_Memorystore(&conf->secureChannelPKI, &defaultApplicationGroup,
1542
0
                                                 &list, conf->logging, &paramsMap);
1543
0
        if(retval != UA_STATUSCODE_GOOD) {
1544
0
            UA_TrustListDataType_clear(&list);
1545
0
            return retval;
1546
0
        }
1547
1548
0
        UA_NodeId defaultUserTokenGroup =
1549
0
            UA_NS0ID(SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP);
1550
0
        retval = UA_CertificateGroup_Memorystore(&conf->sessionPKI, &defaultUserTokenGroup,
1551
0
                                                 &list, conf->logging, &paramsMap);
1552
0
        if(retval != UA_STATUSCODE_GOOD) {
1553
0
            UA_TrustListDataType_clear(&list);
1554
0
            return retval;
1555
0
        }
1556
0
        UA_TrustListDataType_clear(&list);
1557
0
    } else {
1558
0
        UA_LOG_WARNING(conf->logging, UA_LOGCATEGORY_APPLICATION,
1559
0
                       "Empty trustlist passed. Leaving the previously "
1560
0
                       "configured certificate verification in place");
1561
0
    }
1562
1563
0
    retval = UA_ServerConfig_addAllSecureSecurityPolicies(conf, certificate, privateKey);
1564
1565
0
    if(retval == UA_STATUSCODE_GOOD) {
1566
0
        retval = UA_AccessControl_default(conf, false, NULL, 0, NULL);
1567
0
    }
1568
0
    if(retval != UA_STATUSCODE_GOOD) {
1569
0
        UA_ServerConfig_clear(conf);
1570
0
        return retval;
1571
0
    }
1572
1573
0
    retval = UA_ServerConfig_addAllSecureEndpoints(conf);
1574
0
    if(retval != UA_STATUSCODE_GOOD) {
1575
0
        UA_ServerConfig_clear(conf);
1576
0
        return retval;
1577
0
    }
1578
1579
0
    return UA_STATUSCODE_GOOD;
1580
0
}
1581
1582
#if defined(__linux__) || defined(UA_ARCHITECTURE_WIN32)
1583
1584
UA_StatusCode
1585
UA_ServerConfig_addSecurityPolicy_Filestore(UA_ServerConfig *config,
1586
                                            UA_SecurityPolicy *innerPolicy,
1587
0
                                            const UA_String storePath) {
1588
    /* Allocate the SecurityPolicies */
1589
0
    UA_SecurityPolicy *tmp = (UA_SecurityPolicy *)
1590
0
        UA_realloc(config->securityPolicies,
1591
0
                   sizeof(UA_SecurityPolicy) * (1 + config->securityPoliciesSize));
1592
0
    if(!tmp)
1593
0
        return UA_STATUSCODE_BADOUTOFMEMORY;
1594
0
    config->securityPolicies = tmp;
1595
1596
0
    UA_StatusCode retval =
1597
0
        UA_SecurityPolicy_Filestore(&config->securityPolicies[config->securityPoliciesSize],
1598
0
                                    innerPolicy, storePath);
1599
0
    if(retval != UA_STATUSCODE_GOOD) {
1600
0
        if(config->securityPoliciesSize == 0) {
1601
0
            UA_free(config->securityPolicies);
1602
0
            config->securityPolicies = NULL;
1603
0
        }
1604
0
        return retval;
1605
0
    }
1606
1607
0
    config->securityPoliciesSize++;
1608
0
    return UA_STATUSCODE_GOOD;
1609
0
}
1610
1611
UA_StatusCode
1612
UA_ServerConfig_addSecurityPolicies_Filestore(UA_ServerConfig *config,
1613
                                              const UA_ByteString *certificate,
1614
                                              const UA_ByteString *privateKey,
1615
0
                                              const UA_String storePath) {
1616
0
    UA_StatusCode retval = UA_STATUSCODE_GOOD;
1617
0
    UA_Boolean onlySecure = false;
1618
0
    UA_Boolean onlyNone = false;
1619
1620
    /* Populate the SecurityPolicies */
1621
0
    UA_ByteString localCertificate = UA_BYTESTRING_NULL;
1622
0
    UA_ByteString localPrivateKey  = UA_BYTESTRING_NULL;
1623
1624
0
    if(certificate)
1625
0
        localCertificate = *certificate;
1626
0
    if(privateKey)
1627
0
        localPrivateKey = *privateKey;
1628
1629
0
    if(certificate && privateKey) {
1630
0
        size_t certificateKeyLength = 0;
1631
0
        if(UA_CertificateUtils_getKeySize((UA_ByteString*)(uintptr_t)certificate,
1632
0
                                          &certificateKeyLength) == UA_STATUSCODE_GOOD &&
1633
0
           certificateKeyLength > 2048)
1634
0
            onlySecure = true;
1635
0
    } else {
1636
0
        onlyNone = true;
1637
0
    }
1638
1639
    /* Load the private key and convert to the DER format. Use an empty password
1640
     * on the first try -- maybe the key does not require a password. */
1641
0
    UA_ByteString decryptedPrivateKey = UA_BYTESTRING_NULL;
1642
0
    UA_ByteString keyPassword = UA_BYTESTRING_NULL;
1643
0
    UA_StatusCode keySuccess = UA_STATUSCODE_GOOD;
1644
1645
0
    if(privateKey && privateKey->length > 0)
1646
0
        keySuccess = UA_CertificateUtils_decryptPrivateKey(localPrivateKey, keyPassword,
1647
0
                                              &decryptedPrivateKey);
1648
1649
    /* Get the password and decrypt. An application might want to loop / retry
1650
     * here to allow users to correct their entry. */
1651
0
    if(keySuccess != UA_STATUSCODE_GOOD) {
1652
0
        if(config->privateKeyPasswordCallback)
1653
0
            keySuccess = config->privateKeyPasswordCallback(config, &keyPassword);
1654
0
        else
1655
0
            keySuccess = readPrivateKeyPassword(&keyPassword);
1656
0
        if(keySuccess != UA_STATUSCODE_GOOD)
1657
0
            return keySuccess;
1658
0
        keySuccess = UA_CertificateUtils_decryptPrivateKey(localPrivateKey, keyPassword,
1659
0
                                              &decryptedPrivateKey);
1660
0
        UA_ByteString_memZero(&keyPassword);
1661
0
        UA_ByteString_clear(&keyPassword);
1662
0
    }
1663
0
    if(keySuccess != UA_STATUSCODE_GOOD)
1664
0
        return keySuccess;
1665
1666
0
    if(onlyNone) {
1667
        /* None */
1668
0
        UA_SecurityPolicy *nonePolicy =
1669
0
            (UA_SecurityPolicy*)UA_calloc(1, sizeof(UA_SecurityPolicy));
1670
0
        if(!nonePolicy) {
1671
0
            UA_ByteString_memZero(&decryptedPrivateKey);
1672
0
            UA_ByteString_clear(&decryptedPrivateKey);
1673
0
            return UA_STATUSCODE_BADOUTOFMEMORY;
1674
0
        }
1675
0
        retval = UA_SecurityPolicy_None(nonePolicy, localCertificate, config->logging);
1676
0
        if(retval != UA_STATUSCODE_GOOD) {
1677
0
            UA_LOG_WARNING(config->logging, UA_LOGCATEGORY_APPLICATION,
1678
0
                           "Could not add SecurityPolicy#None with error code %s",
1679
0
                           UA_StatusCode_name(retval));
1680
0
            nonePolicy->clear(nonePolicy);
1681
0
            UA_free(nonePolicy);
1682
0
            nonePolicy = NULL;
1683
0
        } else {
1684
0
            retval = UA_ServerConfig_addSecurityPolicy_Filestore(config, nonePolicy, storePath);
1685
0
            if(retval != UA_STATUSCODE_GOOD) {
1686
0
                UA_LOG_WARNING(config->logging, UA_LOGCATEGORY_APPLICATION,
1687
0
                               "Could not add SecurityPolicy#None with error code %s",
1688
0
                               UA_StatusCode_name(retval));
1689
0
            }
1690
0
        }
1691
0
        UA_ByteString_memZero(&decryptedPrivateKey);
1692
0
        UA_ByteString_clear(&decryptedPrivateKey);
1693
0
        return retval;
1694
0
    }
1695
1696
    /* Basic256Sha256 */
1697
0
    UA_SecurityPolicy *basic256Sha256Policy =
1698
0
        (UA_SecurityPolicy*)UA_calloc(1, sizeof(UA_SecurityPolicy));
1699
0
    if(!basic256Sha256Policy) {
1700
0
        UA_ByteString_memZero(&decryptedPrivateKey);
1701
0
        UA_ByteString_clear(&decryptedPrivateKey);
1702
0
        return UA_STATUSCODE_BADOUTOFMEMORY;
1703
0
    }
1704
0
    retval = UA_SecurityPolicy_Basic256Sha256(basic256Sha256Policy, localCertificate,
1705
0
                                              decryptedPrivateKey, config->logging);
1706
0
    if(retval != UA_STATUSCODE_GOOD) {
1707
0
        UA_LOG_WARNING(config->logging, UA_LOGCATEGORY_APPLICATION,
1708
0
                       "Could not add SecurityPolicy#Basic256Sha256 with error code %s",
1709
0
                       UA_StatusCode_name(retval));
1710
0
        basic256Sha256Policy->clear(basic256Sha256Policy);
1711
0
        UA_free(basic256Sha256Policy);
1712
0
        basic256Sha256Policy = NULL;
1713
0
    } else {
1714
0
        retval = UA_ServerConfig_addSecurityPolicy_Filestore(config, basic256Sha256Policy, storePath);
1715
0
        if(retval != UA_STATUSCODE_GOOD) {
1716
0
            UA_LOG_WARNING(config->logging, UA_LOGCATEGORY_APPLICATION,
1717
0
                           "Could not add SecurityPolicy#Basic256Sha256 with error code %s",
1718
0
                           UA_StatusCode_name(retval));
1719
0
        }
1720
0
    }
1721
1722
    /* Aes256Sha256RsaPss */
1723
0
    UA_SecurityPolicy *aes256Sha256RsaPssPolicy =
1724
0
        (UA_SecurityPolicy*)UA_calloc(1, sizeof(UA_SecurityPolicy));
1725
0
    if(!aes256Sha256RsaPssPolicy) {
1726
0
        UA_ByteString_memZero(&decryptedPrivateKey);
1727
0
        UA_ByteString_clear(&decryptedPrivateKey);
1728
0
        return UA_STATUSCODE_BADOUTOFMEMORY;
1729
0
    }
1730
0
    retval = UA_SecurityPolicy_Aes256Sha256RsaPss(aes256Sha256RsaPssPolicy, localCertificate,
1731
0
                                                  decryptedPrivateKey, config->logging);
1732
0
    if(retval != UA_STATUSCODE_GOOD) {
1733
0
        UA_LOG_WARNING(config->logging, UA_LOGCATEGORY_APPLICATION,
1734
0
                       "Could not add SecurityPolicy#Aes256Sha256RsaPss with error code %s",
1735
0
                       UA_StatusCode_name(retval));
1736
0
        aes256Sha256RsaPssPolicy->clear(aes256Sha256RsaPssPolicy);
1737
0
        UA_free(aes256Sha256RsaPssPolicy);
1738
0
        aes256Sha256RsaPssPolicy = NULL;
1739
0
    } else {
1740
0
        retval = UA_ServerConfig_addSecurityPolicy_Filestore(config, aes256Sha256RsaPssPolicy, storePath);
1741
0
        if(retval != UA_STATUSCODE_GOOD) {
1742
0
            UA_LOG_WARNING(config->logging, UA_LOGCATEGORY_APPLICATION,
1743
0
                           "Could not add SecurityPolicy#Aes256Sha256RsaPss with error code %s",
1744
0
                           UA_StatusCode_name(retval));
1745
0
        }
1746
0
    }
1747
1748
    /* Aes128Sha256RsaOaep */
1749
0
    UA_SecurityPolicy *aes128Sha256RsaOaepPolicy =
1750
0
        (UA_SecurityPolicy*)UA_calloc(1, sizeof(UA_SecurityPolicy));
1751
0
    if(!aes128Sha256RsaOaepPolicy) {
1752
0
        UA_ByteString_memZero(&decryptedPrivateKey);
1753
0
        UA_ByteString_clear(&decryptedPrivateKey);
1754
0
        return UA_STATUSCODE_BADOUTOFMEMORY;
1755
0
    }
1756
0
    retval = UA_SecurityPolicy_Aes128Sha256RsaOaep(aes128Sha256RsaOaepPolicy, localCertificate,
1757
0
                                                   decryptedPrivateKey, config->logging);
1758
0
    if(retval != UA_STATUSCODE_GOOD) {
1759
0
        UA_LOG_WARNING(config->logging, UA_LOGCATEGORY_APPLICATION,
1760
0
                       "Could not add SecurityPolicy#Aes128Sha256RsaOaep with error code %s",
1761
0
                       UA_StatusCode_name(retval));
1762
0
        aes128Sha256RsaOaepPolicy->clear(aes128Sha256RsaOaepPolicy);
1763
0
        UA_free(aes128Sha256RsaOaepPolicy);
1764
0
        aes128Sha256RsaOaepPolicy = NULL;
1765
0
    } else {
1766
0
        retval = UA_ServerConfig_addSecurityPolicy_Filestore(config, aes128Sha256RsaOaepPolicy, storePath);
1767
0
        if(retval != UA_STATUSCODE_GOOD) {
1768
0
            UA_LOG_WARNING(config->logging, UA_LOGCATEGORY_APPLICATION,
1769
0
                           "Could not add SecurityPolicy#Aes128Sha256RsaOaep with error code %s",
1770
0
                           UA_StatusCode_name(retval));
1771
0
        }
1772
0
    }
1773
1774
0
    if(onlySecure) {
1775
0
        UA_ByteString_memZero(&decryptedPrivateKey);
1776
0
        UA_ByteString_clear(&decryptedPrivateKey);
1777
0
        return UA_STATUSCODE_GOOD;
1778
0
    }
1779
1780
    /* None */
1781
0
    UA_SecurityPolicy *nonePolicy =
1782
0
        (UA_SecurityPolicy*)UA_calloc(1, sizeof(UA_SecurityPolicy));
1783
0
    if(!nonePolicy) {
1784
0
        UA_ByteString_memZero(&decryptedPrivateKey);
1785
0
        UA_ByteString_clear(&decryptedPrivateKey);
1786
0
        return UA_STATUSCODE_BADOUTOFMEMORY;
1787
0
    }
1788
0
    retval = UA_SecurityPolicy_None(nonePolicy, localCertificate, config->logging);
1789
0
    if(retval != UA_STATUSCODE_GOOD) {
1790
0
        UA_LOG_WARNING(config->logging, UA_LOGCATEGORY_APPLICATION,
1791
0
                       "Could not add SecurityPolicy#None with error code %s",
1792
0
                       UA_StatusCode_name(retval));
1793
0
        nonePolicy->clear(nonePolicy);
1794
0
        UA_free(nonePolicy);
1795
0
        nonePolicy = NULL;
1796
0
    } else {
1797
0
        retval = UA_ServerConfig_addSecurityPolicy_Filestore(config, nonePolicy, storePath);
1798
0
        if(retval != UA_STATUSCODE_GOOD) {
1799
0
            UA_LOG_WARNING(config->logging, UA_LOGCATEGORY_APPLICATION,
1800
0
                           "Could not add SecurityPolicy#None with error code %s",
1801
0
                           UA_StatusCode_name(retval));
1802
0
        }
1803
0
    }
1804
1805
    /* Basic128Rsa15 */
1806
0
    UA_SecurityPolicy *basic128Rsa15Policy =
1807
0
        (UA_SecurityPolicy*)UA_calloc(1, sizeof(UA_SecurityPolicy));
1808
0
    if(!basic128Rsa15Policy) {
1809
0
        UA_ByteString_memZero(&decryptedPrivateKey);
1810
0
        UA_ByteString_clear(&decryptedPrivateKey);
1811
0
        return UA_STATUSCODE_BADOUTOFMEMORY;
1812
0
    }
1813
0
    retval = UA_SecurityPolicy_Basic128Rsa15(basic128Rsa15Policy, localCertificate,
1814
0
                                             decryptedPrivateKey, config->logging);
1815
0
    if(retval != UA_STATUSCODE_GOOD) {
1816
0
        UA_LOG_WARNING(config->logging, UA_LOGCATEGORY_APPLICATION,
1817
0
                       "Could not add SecurityPolicy#Basic128Rsa15 with error code %s",
1818
0
                       UA_StatusCode_name(retval));
1819
0
        basic128Rsa15Policy->clear(basic128Rsa15Policy);
1820
0
        UA_free(basic128Rsa15Policy);
1821
0
        basic128Rsa15Policy = NULL;
1822
0
    } else {
1823
0
        retval = UA_ServerConfig_addSecurityPolicy_Filestore(config, basic128Rsa15Policy, storePath);
1824
0
        if(retval != UA_STATUSCODE_GOOD) {
1825
0
            UA_LOG_WARNING(config->logging, UA_LOGCATEGORY_APPLICATION,
1826
0
                           "Could not add SecurityPolicy#Basic128Rsa15 with error code %s",
1827
0
                           UA_StatusCode_name(retval));
1828
0
        }
1829
0
    }
1830
1831
    /* Basic256 */
1832
0
    UA_SecurityPolicy *basic256Policy =
1833
0
        (UA_SecurityPolicy*)UA_calloc(1, sizeof(UA_SecurityPolicy));
1834
0
    if(!basic256Policy) {
1835
0
        UA_ByteString_memZero(&decryptedPrivateKey);
1836
0
        UA_ByteString_clear(&decryptedPrivateKey);
1837
0
        return UA_STATUSCODE_BADOUTOFMEMORY;
1838
0
    }
1839
0
    retval = UA_SecurityPolicy_Basic256(basic256Policy, localCertificate,
1840
0
                                        decryptedPrivateKey, config->logging);
1841
0
    if(retval != UA_STATUSCODE_GOOD) {
1842
0
        UA_LOG_WARNING(config->logging, UA_LOGCATEGORY_APPLICATION,
1843
0
                       "Could not add SecurityPolicy#Basic256 with error code %s",
1844
0
                       UA_StatusCode_name(retval));
1845
0
        basic256Policy->clear(basic256Policy);
1846
0
        UA_free(basic256Policy);
1847
0
        basic256Policy = NULL;
1848
0
    } else {
1849
0
        retval = UA_ServerConfig_addSecurityPolicy_Filestore(config, basic256Policy, storePath);
1850
0
        if(retval != UA_STATUSCODE_GOOD) {
1851
0
            UA_LOG_WARNING(config->logging, UA_LOGCATEGORY_APPLICATION,
1852
0
                           "Could not add SecurityPolicy#Basic256 with error code %s",
1853
0
                           UA_StatusCode_name(retval));
1854
0
        }
1855
0
    }
1856
1857
    /* EccNistP256AesGcm (OpenSSL-only AEAD policy) */
1858
#if defined(UA_ENABLE_ENCRYPTION_OPENSSL)
1859
    UA_SecurityPolicy *eccnistp256AesGcmPolicy =
1860
        (UA_SecurityPolicy*)UA_calloc(1, sizeof(UA_SecurityPolicy));
1861
    if(!eccnistp256AesGcmPolicy) {
1862
        UA_ByteString_memZero(&decryptedPrivateKey);
1863
        UA_ByteString_clear(&decryptedPrivateKey);
1864
        return UA_STATUSCODE_BADOUTOFMEMORY;
1865
    }
1866
    retval = UA_SecurityPolicy_EccNistP256AesGcm(eccnistp256AesGcmPolicy,
1867
                                                  UA_APPLICATIONTYPE_SERVER,
1868
                                                  localCertificate, decryptedPrivateKey,
1869
                                                  config->logging);
1870
    if(retval != UA_STATUSCODE_GOOD) {
1871
        UA_LOG_WARNING(config->logging, UA_LOGCATEGORY_APPLICATION,
1872
                       "Could not add SecurityPolicy#ECC_nistP256_AesGcm with error code %s",
1873
                       UA_StatusCode_name(retval));
1874
        eccnistp256AesGcmPolicy->clear(eccnistp256AesGcmPolicy);
1875
        UA_free(eccnistp256AesGcmPolicy);
1876
        eccnistp256AesGcmPolicy = NULL;
1877
    } else {
1878
        retval = UA_ServerConfig_addSecurityPolicy_Filestore(config, eccnistp256AesGcmPolicy, storePath);
1879
        if(retval != UA_STATUSCODE_GOOD) {
1880
            UA_LOG_WARNING(config->logging, UA_LOGCATEGORY_APPLICATION,
1881
                           "Could not add SecurityPolicy#ECC_nistP256_AesGcm with error code %s",
1882
                           UA_StatusCode_name(retval));
1883
        }
1884
    }
1885
#endif
1886
1887
    /* The non-AEAD ECC SecurityPolicies (EccNistP256/P384,
1888
     * EccBrainpoolP256r1/P384r1) are deprecated (OPC UA Part 7), superseded by
1889
     * their *_AesGcm / *_ChaChaPoly variants. They are not part of the default
1890
     * policy set; use the UA_ServerConfig_addSecurityPolicyEcc* functions to add
1891
     * them explicitly. */
1892
1893
0
    UA_ByteString_memZero(&decryptedPrivateKey);
1894
0
    UA_ByteString_clear(&decryptedPrivateKey);
1895
0
    return UA_STATUSCODE_GOOD;
1896
0
}
1897
1898
UA_EXPORT UA_StatusCode
1899
UA_ServerConfig_setDefaultWithFilestore(UA_ServerConfig *conf,
1900
                                        UA_UInt16 portNumber,
1901
                                        const UA_ByteString *certificate,
1902
                                        const UA_ByteString *privateKey,
1903
0
                                        const UA_String storePath) {
1904
0
    UA_StatusCode retval = setDefaultConfig(conf, portNumber);
1905
0
    if(retval != UA_STATUSCODE_GOOD) {
1906
0
        return retval;
1907
0
    }
1908
1909
0
    if(!storePath.data) {
1910
0
        UA_LOG_ERROR(conf->logging, UA_LOGCATEGORY_APPLICATION,
1911
0
                     "The path to a PKI folder has not been specified");
1912
0
        return UA_STATUSCODE_BADINVALIDARGUMENT;
1913
0
    }
1914
1915
    /* Set up the parameters */
1916
0
    UA_KeyValuePair params[2];
1917
0
    size_t paramsSize = 2;
1918
1919
0
    params[0].key = UA_QUALIFIEDNAME(0, "max-trust-listsize");
1920
0
    UA_Variant_setScalar(&params[0].value, &conf->maxTrustListSize, &UA_TYPES[UA_TYPES_UINT32]);
1921
0
    params[1].key = UA_QUALIFIEDNAME(0, "max-rejected-listsize");
1922
0
    UA_Variant_setScalar(&params[1].value, &conf->maxRejectedListSize, &UA_TYPES[UA_TYPES_UINT32]);
1923
1924
0
    UA_KeyValueMap paramsMap;
1925
0
    paramsMap.map = params;
1926
0
    paramsMap.mapSize = paramsSize;
1927
1928
0
    UA_NodeId defaultApplicationGroup =
1929
0
            UA_NS0ID(SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP);
1930
0
    retval = UA_CertificateGroup_Filestore(&conf->secureChannelPKI, &defaultApplicationGroup,
1931
0
                                           storePath, conf->logging, &paramsMap);
1932
0
    if(retval != UA_STATUSCODE_GOOD)
1933
0
        return retval;
1934
1935
0
    UA_NodeId defaultUserTokenGroup =
1936
0
            UA_NS0ID(SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP);
1937
0
    retval = UA_CertificateGroup_Filestore(&conf->sessionPKI, &defaultUserTokenGroup,
1938
0
                                           storePath, conf->logging, &paramsMap);
1939
0
    if(retval != UA_STATUSCODE_GOOD)
1940
0
        return retval;
1941
1942
0
    retval = UA_ServerConfig_addSecurityPolicies_Filestore(conf, certificate, privateKey, storePath);
1943
1944
0
    if(retval == UA_STATUSCODE_GOOD) {
1945
0
        retval = UA_AccessControl_default(conf, true, NULL, 0, NULL);
1946
0
    }
1947
1948
0
    if(retval == UA_STATUSCODE_GOOD) {
1949
0
        retval = UA_ServerConfig_addAllEndpoints(conf);
1950
0
    }
1951
1952
0
    return retval;
1953
0
}
1954
1955
#endif /* defined(__linux__) || defined(UA_ARCHITECTURE_WIN32) */
1956
1957
#endif /* UA_ENABLE_ENCRYPTION */
1958
1959
#if defined(UA_ENABLE_DISCOVERY) || defined(UA_ENABLE_AMALGAMATION)
1960
1961
/***************************/
1962
/* Default Client Settings */
1963
/***************************/
1964
1965
20
UA_Client * UA_Client_new(void) {
1966
20
    UA_ClientConfig config;
1967
20
    memset(&config, 0, sizeof(UA_ClientConfig));
1968
    /* Set up basic usable config including logger and event loop */
1969
20
    UA_StatusCode res = UA_ClientConfig_setDefault(&config);
1970
20
    if(res != UA_STATUSCODE_GOOD)
1971
0
        return NULL;
1972
20
    return UA_Client_newWithConfig(&config);
1973
20
}
1974
1975
#if defined(UA_ARCHITECTURE_POSIX) || defined(UA_ARCHITECTURE_WIN32) || defined(UA_ARCHITECTURE_ZEPHYR)
1976
1977
struct ClientInterruptContext {
1978
    UA_Client *client;
1979
    UA_Boolean running;
1980
};
1981
1982
static void
1983
interruptClient(UA_InterruptManager *im, uintptr_t interruptHandle,
1984
0
                void *context, const UA_KeyValueMap *parameters) {
1985
0
    struct ClientInterruptContext *ic = (struct ClientInterruptContext*)context;
1986
0
    UA_ClientConfig *config = UA_Client_getConfig(ic->client);
1987
0
    UA_LOG_INFO(config->logging, UA_LOGCATEGORY_APPLICATION, "Stopping the client");
1988
0
    ic->running = false;
1989
0
}
1990
1991
UA_StatusCode
1992
0
UA_Client_runUntilInterrupt(UA_Client *client) {
1993
0
    if(!client)
1994
0
        return UA_STATUSCODE_BADINTERNALERROR;
1995
0
    UA_ClientConfig *config = UA_Client_getConfig(client);
1996
0
    UA_EventLoop *el = config->eventLoop;
1997
0
    if(!el)
1998
0
        return UA_STATUSCODE_BADINTERNALERROR;
1999
2000
    /* Get the interrupt manager */
2001
0
    UA_EventSource *es = el->eventSources;
2002
0
    while(es) {
2003
0
        if(es->eventSourceType == UA_EVENTSOURCETYPE_INTERRUPTMANAGER)
2004
0
            break;
2005
0
        es = es->next;
2006
0
    }
2007
0
    if(!es) {
2008
0
        UA_LOG_ERROR(config->logging, UA_LOGCATEGORY_APPLICATION,
2009
0
                       "No Interrupt EventSource configured");
2010
0
        return UA_STATUSCODE_BADINTERNALERROR;
2011
0
    }
2012
0
    UA_InterruptManager *im = (UA_InterruptManager*)es;
2013
2014
    /* Register the interrupt */
2015
0
    struct ClientInterruptContext ic;
2016
0
    ic.client = client;
2017
0
    ic.running = true;
2018
0
    UA_StatusCode res =
2019
0
        im->registerInterrupt(im, SIGINT, &UA_KEYVALUEMAP_NULL,
2020
0
                              interruptClient, &ic);
2021
0
    if(res != UA_STATUSCODE_GOOD) {
2022
0
        UA_LOG_ERROR(config->logging, UA_LOGCATEGORY_APPLICATION,
2023
0
                     "Could not register the interrupt with status code %s",
2024
0
                     UA_StatusCode_name(res));
2025
0
        return res;
2026
0
    }
2027
2028
    /* Run the client */
2029
0
    while(ic.running) {
2030
0
        res = UA_Client_run_iterate(client, 100);
2031
0
        if(res != UA_STATUSCODE_GOOD)
2032
0
            break;
2033
0
    }
2034
2035
    /* Deregister the interrupt */
2036
0
    im->deregisterInterrupt(im, SIGINT);
2037
0
    return res;
2038
0
}
2039
2040
#endif /* defined(UA_ARCHITECTURE_POSIX) || defined(UA_ARCHITECTURE_WIN32) */
2041
2042
UA_StatusCode
2043
20
UA_ClientConfig_setDefault(UA_ClientConfig *config) {
2044
    /* The following fields are untouched and OK to leave as NULL or 0:
2045
     *  clientContext
2046
     *  userIdentityToken
2047
     *  securityMode
2048
     *  securityPolicyUri
2049
     *  endpoint
2050
     *  userTokenPolicy
2051
     *  customDataTypes
2052
     *  connectivityCheckInterval
2053
     *  stateCallback
2054
     *  inactivityCallback
2055
     *  outStandingPublishRequests
2056
     *  subscriptionInactivityCallback
2057
     *  sessionLocaleIds
2058
     *  sessionLocaleIdsSize */
2059
2060
20
    if(config->timeout == 0)
2061
20
        config->timeout = 5 * 1000; /* 5 seconds */
2062
20
    if(config->secureChannelLifeTime == 0)
2063
20
        config->secureChannelLifeTime = 10 * 60 * 1000; /* 10 minutes */
2064
2065
20
    if(config->logging == NULL)
2066
0
        config->logging = UA_Log_Stdout_new(UA_LOGLEVEL_INFO);
2067
2068
    /* EventLoop */
2069
20
    if(config->eventLoop == NULL) {
2070
#if defined(UA_ARCHITECTURE_ZEPHYR)
2071
        config->eventLoop = UA_EventLoop_new_Zephyr(config->logging);
2072
#elif defined(UA_ARCHITECTURE_LWIP)
2073
        config->eventLoop = UA_EventLoop_new_LWIP(config->logging, NULL);
2074
#else
2075
20
        config->eventLoop = UA_EventLoop_new_POSIX(config->logging);
2076
20
#endif
2077
20
        config->externalEventLoop = false;
2078
2079
        /* Add the TCP connection manager */
2080
#if defined(UA_ARCHITECTURE_ZEPHYR)
2081
        UA_ConnectionManager *tcpCM =
2082
            UA_ConnectionManager_new_Zephyr_TCP(UA_STRING("tcp connection manager"));
2083
#elif defined(UA_ARCHITECTURE_LWIP)
2084
        UA_ConnectionManager *tcpCM =
2085
            UA_ConnectionManager_new_LWIP_TCP(UA_STRING("tcp connection manager"));
2086
#else
2087
20
        UA_ConnectionManager *tcpCM =
2088
20
            UA_ConnectionManager_new_POSIX_TCP(UA_STRING("tcp connection manager"));
2089
20
#endif
2090
20
        config->eventLoop->registerEventSource(config->eventLoop, (UA_EventSource *)tcpCM);
2091
2092
#if defined(UA_ARCHITECTURE_LWIP)
2093
        UA_ConnectionManager *udpCM =
2094
            UA_ConnectionManager_new_LWIP_UDP(UA_STRING("udp connection manager"));
2095
        if(udpCM)
2096
            config->eventLoop->registerEventSource(config->eventLoop, (UA_EventSource *)udpCM);
2097
#elif !defined(UA_ARCHITECTURE_ZEPHYR)
2098
        /* Add the UDP connection manager */
2099
20
        UA_ConnectionManager *udpCM =
2100
20
            UA_ConnectionManager_new_POSIX_UDP(UA_STRING("udp connection manager"));
2101
20
        config->eventLoop->registerEventSource(config->eventLoop, (UA_EventSource *)udpCM);
2102
20
#endif
2103
2104
20
#if !defined(UA_ARCHITECTURE_ZEPHYR) && !defined(UA_ARCHITECTURE_LWIP)
2105
        /* Add the interrupt manager */
2106
20
        UA_InterruptManager *im = UA_InterruptManager_new_POSIX(UA_STRING("interrupt manager"));
2107
20
        if(im) {
2108
20
            config->eventLoop->registerEventSource(config->eventLoop, &im->eventSource);
2109
20
        } else {
2110
0
            UA_LOG_ERROR(config->logging, UA_LOGCATEGORY_APPLICATION,
2111
0
                         "Cannot create the Interrupt Manager (only relevant if used)");
2112
0
        }
2113
20
#endif
2114
20
    }
2115
2116
20
    if(config->localConnectionConfig.recvBufferSize == 0)
2117
20
        config->localConnectionConfig = UA_ConnectionConfig_default;
2118
2119
20
    if(!config->certificateVerification.logging) {
2120
20
        config->certificateVerification.logging = config->logging;
2121
20
    }
2122
2123
20
#ifdef UA_ENABLE_ENCRYPTION
2124
    /* Limits for TrustList */
2125
20
    config->maxTrustListSize = 0;
2126
20
    config->maxRejectedListSize = 0;
2127
20
#endif
2128
2129
20
    if(!config->certificateVerification.verifyCertificate) {
2130
        /* Certificate Verification that accepts every certificate. Can be
2131
         * overwritten when the policy is specialized. */
2132
20
        UA_CertificateGroup_AcceptAll(&config->certificateVerification);
2133
20
    }
2134
2135
    /* With encryption enabled, the applicationUri needs to match the URI from
2136
     * the certificate */
2137
20
    if(!config->clientDescription.applicationUri.data)
2138
20
        config->clientDescription.applicationUri = UA_STRING_ALLOC(APPLICATION_URI);
2139
20
    if(config->clientDescription.applicationType == 0)
2140
20
        config->clientDescription.applicationType = UA_APPLICATIONTYPE_CLIENT;
2141
2142
20
    if(config->securityPoliciesSize == 0) {
2143
20
        config->securityPolicies = (UA_SecurityPolicy*)UA_malloc(sizeof(UA_SecurityPolicy));
2144
20
        if(!config->securityPolicies)
2145
0
            return UA_STATUSCODE_BADOUTOFMEMORY;
2146
20
        UA_StatusCode retval = UA_SecurityPolicy_None(config->securityPolicies,
2147
20
                                                      UA_BYTESTRING_NULL, config->logging);
2148
20
        if(retval != UA_STATUSCODE_GOOD) {
2149
0
            UA_free(config->securityPolicies);
2150
0
            config->securityPolicies = NULL;
2151
0
            return retval;
2152
0
        }
2153
20
        config->securityPoliciesSize = 1;
2154
20
    }
2155
2156
    /* Initialize authSecurityPolicies with the None policy as a fallback.
2157
     * This is needed so that non-X509 token types (e.g. username/password,
2158
     * anonymous) can look up a matching SecurityPolicy for authentication.
2159
     * When UA_ClientConfig_setAuthenticationCert is called later, this gets
2160
     * replaced with the full set of authentication SecurityPolicies. */
2161
20
    if(config->authSecurityPoliciesSize == 0) {
2162
20
        config->authSecurityPolicies =
2163
20
            (UA_SecurityPolicy*)UA_malloc(sizeof(UA_SecurityPolicy));
2164
20
        if(!config->authSecurityPolicies)
2165
0
            return UA_STATUSCODE_BADOUTOFMEMORY;
2166
20
        UA_StatusCode retval =
2167
20
            UA_SecurityPolicy_None(config->authSecurityPolicies,
2168
20
                                   UA_BYTESTRING_NULL, config->logging);
2169
20
        if(retval != UA_STATUSCODE_GOOD) {
2170
0
            UA_free(config->authSecurityPolicies);
2171
0
            config->authSecurityPolicies = NULL;
2172
0
            return retval;
2173
0
        }
2174
20
        config->authSecurityPoliciesSize = 1;
2175
20
    }
2176
2177
20
    if(config->requestedSessionTimeout == 0)
2178
20
        config->requestedSessionTimeout = 1200000;
2179
2180
20
#ifdef UA_ENABLE_SUBSCRIPTIONS
2181
20
    if(config->outStandingPublishRequests == 0)
2182
20
        config->outStandingPublishRequests = 10;
2183
20
#endif
2184
2185
20
    return UA_STATUSCODE_GOOD;
2186
20
}
2187
2188
#ifdef UA_ENABLE_ENCRYPTION
2189
2190
static UA_StatusCode
2191
clientConfig_setAuthenticationSecurityPolicies(UA_ClientConfig *config,
2192
                                               UA_ByteString certificateAuth,
2193
0
                                               UA_ByteString privateKeyAuth) {
2194
0
    for(size_t i = 0; i < config->authSecurityPoliciesSize; i++) {
2195
0
        config->authSecurityPolicies[i].clear(&config->authSecurityPolicies[i]);
2196
0
    }
2197
2198
0
    UA_SecurityPolicy *sp = (UA_SecurityPolicy*)
2199
0
        UA_realloc(config->authSecurityPolicies, sizeof(UA_SecurityPolicy) * SECURITY_POLICY_SIZE);
2200
0
    if(!sp)
2201
0
        return UA_STATUSCODE_BADOUTOFMEMORY;
2202
0
    config->authSecurityPolicies = sp;
2203
0
    config->authSecurityPoliciesSize = 0;
2204
2205
0
    addAllSecurityPolicies(sp, &config->authSecurityPoliciesSize,
2206
0
                           certificateAuth, privateKeyAuth, false,
2207
0
                           UA_APPLICATIONTYPE_CLIENT, config->logging);
2208
2209
0
    if(config->authSecurityPoliciesSize == 0) {
2210
0
        UA_free(config->authSecurityPolicies);
2211
0
        config->authSecurityPolicies = NULL;
2212
0
    }
2213
2214
0
    return UA_STATUSCODE_GOOD;
2215
0
}
2216
2217
static UA_StatusCode
2218
clientConfig_setSecurityPolicies(UA_ClientConfig *config,
2219
                                 UA_ByteString certificateAuth,
2220
0
                                 UA_ByteString privateKeyAuth) {
2221
0
    for(size_t i = 0; i < config->securityPoliciesSize; i++) {
2222
0
        config->securityPolicies[i].clear(&config->securityPolicies[i]);
2223
0
    }
2224
2225
0
    UA_SecurityPolicy *sp = (UA_SecurityPolicy*)
2226
0
        UA_realloc(config->securityPolicies,
2227
0
                   sizeof(UA_SecurityPolicy) * SECURITY_POLICY_SIZE);
2228
0
    if(!sp)
2229
0
        return UA_STATUSCODE_BADOUTOFMEMORY;
2230
0
    config->securityPolicies = sp;
2231
0
    config->securityPoliciesSize = 0;
2232
2233
0
    addAllSecurityPolicies(sp, &config->securityPoliciesSize,
2234
0
                           certificateAuth, privateKeyAuth, false,
2235
0
                           UA_APPLICATIONTYPE_CLIENT, config->logging);
2236
2237
0
    if(config->securityPoliciesSize == 0) {
2238
0
        UA_free(config->securityPolicies);
2239
0
        config->securityPolicies = NULL;
2240
0
    }
2241
2242
0
    return UA_STATUSCODE_GOOD;
2243
0
}
2244
2245
UA_StatusCode
2246
UA_ClientConfig_setDefaultEncryption(UA_ClientConfig *config,
2247
                                     UA_ByteString localCertificate, UA_ByteString privateKey,
2248
                                     const UA_ByteString *trustList, size_t trustListSize,
2249
0
                                     const UA_ByteString *revocationList, size_t revocationListSize) {
2250
0
    UA_StatusCode retval = UA_ClientConfig_setDefault(config);
2251
0
    if(retval != UA_STATUSCODE_GOOD)
2252
0
        return retval;
2253
2254
0
    if(trustListSize > 0) {
2255
0
        UA_TrustListDataType list;
2256
0
        UA_TrustListDataType_init(&list);
2257
0
        list.specifiedLists |= UA_TRUSTLISTMASKS_TRUSTEDCERTIFICATES;
2258
0
        retval = UA_Array_copy(trustList, trustListSize,
2259
0
                               (void**)&list.trustedCertificates,
2260
0
                               &UA_TYPES[UA_TYPES_BYTESTRING]);
2261
0
        if(retval != UA_STATUSCODE_GOOD)
2262
0
            return retval;
2263
0
        list.trustedCertificatesSize = trustListSize;
2264
2265
0
        if(revocationListSize > 0) {
2266
0
            list.specifiedLists |= UA_TRUSTLISTMASKS_TRUSTEDCRLS;
2267
0
            retval = UA_Array_copy(revocationList, revocationListSize,
2268
0
                                   (void**)&list.trustedCrls,
2269
0
                                   &UA_TYPES[UA_TYPES_BYTESTRING]);
2270
0
            if(retval != UA_STATUSCODE_GOOD) {
2271
0
                UA_TrustListDataType_clear(&list);
2272
0
                return retval;
2273
0
            }
2274
0
            list.trustedCrlsSize = revocationListSize;
2275
0
        }
2276
2277
        /* Set up the parameters */
2278
0
        UA_KeyValuePair params[2];
2279
0
        size_t paramsSize = 2;
2280
2281
0
        params[0].key = UA_QUALIFIEDNAME(0, "max-trust-listsize");
2282
0
        UA_Variant_setScalar(&params[0].value, &config->maxTrustListSize,
2283
0
                             &UA_TYPES[UA_TYPES_UINT32]);
2284
0
        params[1].key = UA_QUALIFIEDNAME(0, "max-rejected-listsize");
2285
0
        UA_Variant_setScalar(&params[1].value, &config->maxRejectedListSize,
2286
0
                             &UA_TYPES[UA_TYPES_UINT32]);
2287
2288
0
        UA_KeyValueMap paramsMap;
2289
0
        paramsMap.map = params;
2290
0
        paramsMap.mapSize = paramsSize;
2291
2292
0
        if(config->certificateVerification.clear)
2293
0
            config->certificateVerification.clear(&config->certificateVerification);
2294
0
        UA_NodeId defaultApplicationGroup =
2295
0
            UA_NS0ID(SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP);
2296
0
        retval = UA_CertificateGroup_Memorystore(&config->certificateVerification,
2297
0
                                                 &defaultApplicationGroup, &list,
2298
0
                                                 config->logging, &paramsMap);
2299
0
        UA_TrustListDataType_clear(&list);
2300
0
        if(retval != UA_STATUSCODE_GOOD)
2301
0
            return retval;
2302
0
    } else {
2303
0
        UA_LOG_WARNING(config->logging, UA_LOGCATEGORY_SECURITYPOLICY,
2304
0
                       "Empty trustlist passed. Leaving the previously "
2305
0
                       "configured certificate verification in place");
2306
0
    }
2307
2308
    /* Load the private key and convert to the DER format. Use an empty password
2309
     * on the first try -- maybe the key does not require a password. */
2310
0
    UA_ByteString decryptedPrivateKey = UA_BYTESTRING_NULL;
2311
0
    UA_ByteString keyPassword = UA_BYTESTRING_NULL;
2312
0
    UA_StatusCode keySuccess = UA_STATUSCODE_GOOD;
2313
2314
0
    if(privateKey.length > 0)
2315
0
        keySuccess = UA_CertificateUtils_decryptPrivateKey(privateKey, keyPassword,
2316
0
                                                           &decryptedPrivateKey);
2317
2318
    /* Get the password and decrypt. An application might want to loop / retry
2319
     * here to allow users to correct their entry. */
2320
0
    if(keySuccess != UA_STATUSCODE_GOOD) {
2321
0
        if(config->privateKeyPasswordCallback)
2322
0
            keySuccess = config->privateKeyPasswordCallback(config, &keyPassword);
2323
0
        else
2324
0
            keySuccess = readPrivateKeyPassword(&keyPassword);
2325
0
        if(keySuccess != UA_STATUSCODE_GOOD)
2326
0
            return keySuccess;
2327
0
        keySuccess = UA_CertificateUtils_decryptPrivateKey(privateKey, keyPassword, &decryptedPrivateKey);
2328
0
        UA_ByteString_memZero(&keyPassword);
2329
0
        UA_ByteString_clear(&keyPassword);
2330
0
    }
2331
0
    if(keySuccess != UA_STATUSCODE_GOOD)
2332
0
        return keySuccess;
2333
2334
0
    clientConfig_setSecurityPolicies(config, localCertificate, decryptedPrivateKey);
2335
0
    clientConfig_setAuthenticationSecurityPolicies(config, localCertificate, decryptedPrivateKey);
2336
2337
0
    UA_ByteString_memZero(&decryptedPrivateKey);
2338
0
    UA_ByteString_clear(&decryptedPrivateKey);
2339
2340
0
    return UA_STATUSCODE_GOOD;
2341
0
}
2342
#endif
2343
2344
#if defined(UA_ENABLE_ENCRYPTION_OPENSSL) || defined(UA_ENABLE_ENCRYPTION_MBEDTLS)
2345
UA_StatusCode
2346
UA_ClientConfig_setAuthenticationCert(UA_ClientConfig *config,
2347
                                      UA_ByteString certificateAuth,
2348
0
                                      UA_ByteString privateKeyAuth) {
2349
#ifdef UA_ENABLE_ENCRYPTION_LIBRESSL
2350
    UA_LOG_ERROR(config->logging, UA_LOGCATEGORY_APPLICATION,
2351
                 "Certificate authentication with LibreSSL as crypto backend is not supported.");
2352
    return UA_STATUSCODE_BADNOTIMPLEMENTED;
2353
#endif
2354
2355
    /* Create UserIdentityToken */
2356
0
    UA_X509IdentityToken* identityToken = UA_X509IdentityToken_new();
2357
0
    if(!identityToken)
2358
0
        return UA_STATUSCODE_BADOUTOFMEMORY;
2359
    /* Don't set identityToken->policyId. This is taken from the appropriate
2360
     * endpoint at runtime. */
2361
0
    UA_StatusCode retval = UA_ByteString_copy(&certificateAuth, &identityToken->certificateData);
2362
0
    if(retval != UA_STATUSCODE_GOOD)
2363
0
        return retval;
2364
0
    UA_ExtensionObject_clear(&config->userIdentityToken);
2365
0
    config->userIdentityToken.encoding = UA_EXTENSIONOBJECT_DECODED;
2366
0
    config->userIdentityToken.content.decoded.type = &UA_TYPES[UA_TYPES_X509IDENTITYTOKEN];
2367
0
    config->userIdentityToken.content.decoded.data = identityToken;
2368
2369
    /* Populate SecurityPolicies */
2370
0
    return clientConfig_setAuthenticationSecurityPolicies(config, certificateAuth, privateKeyAuth);
2371
0
}
2372
#endif
2373
2374
#endif /* UA_ENABLE_DISCOVERY OR UA_ENABLE_AMALGAMATION*/