Coverage Report

Created: 2026-09-27 07:10

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