Coverage Report

Created: 2025-10-13 06:32

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