Coverage Report

Created: 2026-05-16 06:50

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