Coverage Report

Created: 2026-11-12 06:54

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