open62541-sys 0.6.1

Low-level, unsafe bindings for the C11 library open62541, an open source and free implementation of OPC UA (OPC Unified Architecture).
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 *    Copyright 2014-2017 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
 *    Copyright 2014, 2017 (c) Florian Palm
 *    Copyright 2015 (c) LEvertz
 *    Copyright 2015-2016 (c) Sten GrĂ¼ner
 *    Copyright 2015 (c) Chris Iatrou
 *    Copyright 2015-2016 (c) Oleksiy Vasylyev
 *    Copyright 2017 (c) Stefan Profanter, fortiss GmbH
 *    Copyright 2021 (c) Fraunhofer IOSB (Author: Jan Hermes)
 *    Copyright 2025 (c) Siemens AG (Author: Tin Raic)
 *    Copyright 2026 (c) o6 Automation GmbH (Author: Julius Pfrommer)
 */

#ifndef UA_UTIL_H_
#define UA_UTIL_H_

#define UA_INTERNAL
#include <open62541/types.h>
#include <open62541/util.h>
#include <open62541/statuscodes.h>

#include <open62541/plugin/log.h>
#include <open62541/plugin/securitypolicy.h>

#include "../ua_types_encoding_binary.h"
#include "../ua_securechannel.h"

_UA_BEGIN_DECLS

/* Macro-Expand for MSVC workarounds */
#define UA_MACRO_EXPAND(x) x

/* Often-used macro to get the beginning of the parent data structure */
#ifndef container_of
# define container_of(ptr, type, member) \
    (type *)((uintptr_t)ptr - offsetof(type,member))
#endif

/* Try if the type of the value can be adjusted "in situ" to the target type.
 * That can be done, for example, to map between int32 and an enum.
 *
 * This can also "unwrap" a type. For example: string -> array of bytes
 *
 * If value->data is changed during adjustType, free the pointer afterwards (if
 * you did not keep the original variant for _clear). */
void
adjustType(UA_Variant *value, const UA_DataType *targetType);

/* Short names for integer. These are not exposed on the public API, since many
 * user-applications make the same definitions in their headers. */
typedef UA_Byte u8;
typedef UA_SByte i8;
typedef UA_UInt16 u16;
typedef UA_Int16 i16;
typedef UA_UInt32 u32;
typedef UA_Int32 i32;
typedef UA_UInt64 u64;
typedef UA_Int64 i64;
typedef UA_StatusCode status;

/* Well-known ReferenceTypes */
UA_StatusCode
lookupRefType(UA_Server *server, UA_QualifiedName *qn, UA_NodeId *outRefTypeId);

/* Returns the canonical BrowseName of the ReferenceType or the encoded
 * NodeId. The outBN is assumed to be pre-allocated with a buffer. This fails if
 * the NodeId contains an '>' character, which makes the parsing ambigous. */
UA_StatusCode
getRefTypeBrowseName(const UA_NodeId *refTypeId, UA_String *outBN);

typedef enum {
    UA_ESCAPING_NONE = 0,
    UA_ESCAPING_AND,
    UA_ESCAPING_AND_EXTENDED,
    UA_ESCAPING_PERCENT,
    UA_ESCAPING_PERCENT_EXTENDED
} UA_Escaping;

static UA_INLINE UA_Boolean
isReservedAnd(u8 c) {
    return (c == '/' || c == '.' || c == '<' || c == '>' ||
            c == ':' || c == '#' || c == '!' || c == '&');
}

static UA_INLINE UA_Boolean
isReservedAndExtended(u8 c) {
    return (isReservedAnd(c) || c == ',' || c == '(' || c == ')' ||
            c == '[' || c == ']' || c <= ' ' || c == 127);
}

static UA_INLINE UA_Boolean
isReservedPercent(u8 c) {
    return (c == ';'  || c == '%' || c <= ' ' || c == 127);
}

static UA_INLINE UA_Boolean
isReservedPercentExtended(u8 c) {
    return (isReservedPercent(c) || c == ':' || c == '#' || c == '[' || c == ']' ||
            c == '&' || c == '(' || c == ')' || c == ',' || c == '<' || c == '>' ||
            c == '`' || c == '/' || c == '\\' || c == '"' || c == '\'' );
}

/* Unescape string. The copyEscape boolean indicates whether a copy of the
 * string should be made if an escaped character is found. Otherwise the string
 * is unescaped in-place. */
UA_StatusCode
UA_String_unescape(UA_String *str, UA_Boolean copyEscape, UA_Escaping esc);

/* Size of the string with the escaping */
size_t
UA_String_escapedSize(const UA_String s, UA_Escaping esc);

/* Insert string with escaping at the defined position.
 * Returns the length of the inserted escaped string.
 * This is an unsafe procedure if not enough space is available. */
size_t
UA_String_escapeInsert(u8 *pos, const UA_String s2, UA_Escaping esc);

/* Escape s2 and append it to s. Memory is allocated internally. */
UA_StatusCode
UA_String_escapeAppend(UA_String *s, const UA_String s2, UA_Escaping esc);

/* Case insensitive lookup. Returns UA_ATTRIBUTEID_INVALID if not found. */
UA_AttributeId
UA_AttributeId_fromName(const UA_String name);

/* Special version of NodeId_print where the identifier component is escaped as
 * well (not just the NamespaceUri). For percent-escaping (URL format), the
 * ByteString body is in base64url format (no +/, no =-padding). */
UA_StatusCode
nodeId_printEscape(const UA_NodeId *id, UA_String *output,
                   const UA_NamespaceMapping *nsMapping, UA_Escaping idEsc);

#ifdef UA_TYPES_SIMPLEATTRIBUTEOPERAND
UA_StatusCode
sao_parseWithDefaultNsIdx(UA_SimpleAttributeOperand *sao,
                          const UA_String str, UA_UInt16 defaultNsIndex);
#endif

UA_StatusCode
encodeDateTime(const UA_DateTime dt, UA_String *output);

/***************/
/* Log Helpers */
/***************/

extern char * securityModeNames[4];

/**
 * Error checking macros
 */

static UA_INLINE UA_Boolean
isGood(UA_StatusCode code) {
    return code == UA_STATUSCODE_GOOD;
}

static UA_INLINE UA_Boolean
isNonNull(const void *ptr) {
    return ptr != NULL;
}

static UA_INLINE UA_Boolean
isTrue(uint8_t expr) {
    return expr;
}

#define UA_CHECK(A, EVAL_ON_ERROR)                                                       \
    do {                                                                                 \
        if(UA_UNLIKELY(!isTrue(A))) {                                                    \
            EVAL_ON_ERROR;                                                               \
        }                                                                                \
    } while(0)

#define UA_CHECK_STATUS(STATUSCODE, EVAL_ON_ERROR)                                       \
    UA_CHECK(isGood(STATUSCODE), EVAL_ON_ERROR)

#define UA_CHECK_MEM(STATUSCODE, EVAL_ON_ERROR)                                       \
    UA_CHECK(isNonNull(STATUSCODE), EVAL_ON_ERROR)

#ifdef UA_DEBUG_FILE_LINE_INFO
#define UA_CHECK_LOG_INTERNAL(A, STATUSCODE, EVAL, LOG, LOGGER, CAT, MSG, ...)           \
    UA_MACRO_EXPAND(                                                                     \
        UA_CHECK(A, LOG(LOGGER, CAT, "" MSG "%s (%s:%d: StatusCode: %s)", __VA_ARGS__,   \
                        __FILE__, __LINE__, UA_StatusCode_name(STATUSCODE));             \
                 EVAL))
#else
#define UA_CHECK_LOG_INTERNAL(A, STATUSCODE, EVAL, LOG, LOGGER, CAT, MSG, ...)           \
    UA_MACRO_EXPAND(                                                                     \
        UA_CHECK(A, LOG(LOGGER, CAT, "" MSG "%s (StatusCode: %s)", __VA_ARGS__,   \
                        UA_StatusCode_name(STATUSCODE));             \
                 EVAL))
#endif

#define UA_CHECK_LOG(A, EVAL, LEVEL, LOGGER, CAT, ...)                                   \
    UA_MACRO_EXPAND(UA_CHECK_LOG_INTERNAL(A, UA_STATUSCODE_BAD, EVAL, UA_LOG_##LEVEL,    \
                                          LOGGER, CAT, __VA_ARGS__, ""))

#define UA_CHECK_STATUS_LOG(STATUSCODE, EVAL, LEVEL, LOGGER, CAT, ...)                   \
    UA_MACRO_EXPAND(UA_CHECK_LOG_INTERNAL(isGood(STATUSCODE), STATUSCODE,  \
                                          EVAL, UA_LOG_##LEVEL, LOGGER, CAT,             \
                                          __VA_ARGS__, ""))

#define UA_CHECK_MEM_LOG(PTR, EVAL, LEVEL, LOGGER, CAT, ...)                   \
    UA_MACRO_EXPAND(UA_CHECK_LOG_INTERNAL(isNonNull(PTR), UA_STATUSCODE_BADOUTOFMEMORY,  \
                                          EVAL, UA_LOG_##LEVEL, LOGGER, CAT,             \
                                          __VA_ARGS__, ""))

/**
 * Check Macros
 * Usage examples:
 *
 *    void *data = malloc(...);
 *    UA_CHECK(data, return error);
 *
 *    UA_StatusCode rv = some_func(...);
 *    UA_CHECK_STATUS(rv, return rv);
 *
 *    UA_Logger *logger = &server->config.logger;
 *    rv = bar_func(...);
 *    UA_CHECK_STATUS_WARN(rv, return rv, logger, UA_LOGCATEGORY_SERVER, "msg & args %s", "arg");
 */
#define UA_CHECK_FATAL(A, EVAL, LOGGER, CAT, ...)                                        \
    UA_MACRO_EXPAND(UA_CHECK_LOG(A, EVAL, FATAL, LOGGER, CAT, __VA_ARGS__))
#define UA_CHECK_ERROR(A, EVAL, LOGGER, CAT, ...)                                        \
    UA_MACRO_EXPAND(UA_CHECK_LOG(A, EVAL, ERROR, LOGGER, CAT, __VA_ARGS__))
#define UA_CHECK_WARN(A, EVAL, LOGGER, CAT, ...)                                         \
    UA_MACRO_EXPAND(UA_CHECK_LOG(A, EVAL, WARNING, LOGGER, CAT, __VA_ARGS__))
#define UA_CHECK_INFO(A, EVAL, LOGGER, CAT, ...)                                         \
    UA_MACRO_EXPAND(UA_CHECK_LOG(A, EVAL, INFO, LOGGER, CAT, __VA_ARGS__))

#define UA_CHECK_STATUS_FATAL(STATUSCODE, EVAL, LOGGER, CAT, ...)                        \
    UA_MACRO_EXPAND(                                                                     \
        UA_CHECK_STATUS_LOG(STATUSCODE, EVAL, FATAL, LOGGER, CAT, __VA_ARGS__))
#define UA_CHECK_STATUS_ERROR(STATUSCODE, EVAL, LOGGER, CAT, ...)                        \
    UA_MACRO_EXPAND(                                                                     \
        UA_CHECK_STATUS_LOG(STATUSCODE, EVAL, ERROR, LOGGER, CAT, __VA_ARGS__))
#define UA_CHECK_STATUS_WARN(STATUSCODE, EVAL, LOGGER, CAT, ...)                         \
    UA_MACRO_EXPAND(                                                                     \
        UA_CHECK_STATUS_LOG(STATUSCODE, EVAL, WARNING, LOGGER, CAT, __VA_ARGS__))
#define UA_CHECK_STATUS_INFO(STATUSCODE, EVAL, LOGGER, CAT, ...)                         \
    UA_MACRO_EXPAND(                                                                     \
        UA_CHECK_STATUS_LOG(STATUSCODE, EVAL, INFO, LOGGER, CAT, __VA_ARGS__))
#define UA_CHECK_STATUS_DEBUG(STATUSCODE, EVAL, LOGGER, CAT, ...)                         \
    UA_MACRO_EXPAND(                                                                     \
        UA_CHECK_STATUS_LOG(STATUSCODE, EVAL, DEBUG, LOGGER, CAT, __VA_ARGS__))

#define UA_CHECK_MEM_FATAL(PTR, EVAL, LOGGER, CAT, ...)                        \
    UA_MACRO_EXPAND(                                                                     \
        UA_CHECK_MEM_LOG(PTR, EVAL, FATAL, LOGGER, CAT, __VA_ARGS__))
#define UA_CHECK_MEM_ERROR(PTR, EVAL, LOGGER, CAT, ...)                        \
    UA_MACRO_EXPAND(                                                                     \
        UA_CHECK_MEM_LOG(PTR, EVAL, ERROR, LOGGER, CAT, __VA_ARGS__))
#define UA_CHECK_MEM_WARN(PTR, EVAL, LOGGER, CAT, ...)                         \
    UA_MACRO_EXPAND(                                                                     \
        UA_CHECK_MEM_LOG(PTR, EVAL, WARNING, LOGGER, CAT, __VA_ARGS__))
#define UA_CHECK_MEM_INFO(PTR, EVAL, LOGGER, CAT, ...)                         \
    UA_MACRO_EXPAND(                                                                     \
        UA_CHECK_MEM_LOG(PTR, EVAL, INFO, LOGGER, CAT, __VA_ARGS__))

/**
 * Utility Functions
 * ----------------- */

#ifdef UA_ENABLE_DISCOVERY_SEMAPHORE
# ifdef UA_ARCHITECTURE_WIN32
#  include <io.h>
#  define UA_fileExists(X) ( _access(X, 0) == 0)
# else
#  include <unistd.h>
#  define UA_fileExists(X) ( access(X, 0) == 0)
# endif
#endif

void
UA_cleanupDataTypeWithCustom(UA_DataTypeArray *customTypes);

/* Get the number of optional fields contained in an structure type */
size_t UA_EXPORT
getCountOfOptionalFields(const UA_DataType *type);

/* Dump packet for debugging / fuzzing */
#ifdef UA_DEBUG_DUMP_PKGS
void UA_EXPORT
UA_dump_hex_pkg(UA_Byte* buffer, size_t bufferLen);
#endif

/* Get pointer to leaf certificate of a specified valid chain of DER encoded
 * certificates */
UA_ByteString getLeafCertificate(UA_ByteString chain);

/* Unions that represent any of the supported request or response message */
typedef union {
    UA_RequestHeader requestHeader;
    UA_FindServersRequest findServersRequest;
    UA_GetEndpointsRequest getEndpointsRequest;
#ifdef UA_ENABLE_DISCOVERY
# ifdef UA_ENABLE_DISCOVERY_MULTICAST
    UA_FindServersOnNetworkRequest findServersOnNetworkRequest;
# endif
    UA_RegisterServerRequest registerServerRequest;
    UA_RegisterServer2Request registerServer2Request;
#endif
    UA_OpenSecureChannelRequest openSecureChannelRequest;
    UA_CreateSessionRequest createSessionRequest;
    UA_ActivateSessionRequest activateSessionRequest;
    UA_CloseSessionRequest closeSessionRequest;
    UA_AddNodesRequest addNodesRequest;
    UA_AddReferencesRequest addReferencesRequest;
    UA_DeleteNodesRequest deleteNodesRequest;
    UA_DeleteReferencesRequest deleteReferencesRequest;
    UA_BrowseRequest browseRequest;
    UA_BrowseNextRequest browseNextRequest;
    UA_TranslateBrowsePathsToNodeIdsRequest translateBrowsePathsToNodeIdsRequest;
    UA_RegisterNodesRequest registerNodesRequest;
    UA_UnregisterNodesRequest unregisterNodesRequest;
    UA_ReadRequest readRequest;
    UA_WriteRequest writeRequest;
#ifdef UA_ENABLE_HISTORIZING
    UA_HistoryReadRequest historyReadRequest;
    UA_HistoryUpdateRequest historyUpdateRequest;
#endif
#ifdef UA_ENABLE_METHODCALLS
    UA_CallRequest callRequest;
#endif
#ifdef UA_ENABLE_SUBSCRIPTIONS
    UA_CreateMonitoredItemsRequest createMonitoredItemsRequest;
    UA_DeleteMonitoredItemsRequest deleteMonitoredItemsRequest;
    UA_ModifyMonitoredItemsRequest modifyMonitoredItemsRequest;
    UA_SetMonitoringModeRequest setMonitoringModeRequest;
    UA_CreateSubscriptionRequest createSubscriptionRequest;
    UA_ModifySubscriptionRequest modifySubscriptionRequest;
    UA_SetPublishingModeRequest setPublishingModeRequest;
    UA_PublishRequest publishRequest;
    UA_RepublishRequest republishRequest;
    UA_DeleteSubscriptionsRequest deleteSubscriptionsRequest;
#endif
} UA_Request;

typedef union {
    UA_ResponseHeader responseHeader;
    UA_FindServersResponse findServersResponse;
    UA_GetEndpointsResponse getEndpointsResponse;
#ifdef UA_ENABLE_DISCOVERY
# ifdef UA_ENABLE_DISCOVERY_MULTICAST
    UA_FindServersOnNetworkResponse findServersOnNetworkResponse;
# endif
    UA_RegisterServerResponse registerServerResponse;
    UA_RegisterServer2Response registerServer2Response;
#endif
    UA_OpenSecureChannelResponse openSecureChannelResponse;
    UA_CreateSessionResponse createSessionResponse;
    UA_ActivateSessionResponse activateSessionResponse;
    UA_CloseSessionResponse closeSessionResponse;
    UA_AddNodesResponse addNodesResponse;
    UA_AddReferencesResponse addReferencesResponse;
    UA_DeleteNodesResponse deleteNodesResponse;
    UA_DeleteReferencesResponse deleteReferencesResponse;
    UA_BrowseResponse browseResponse;
    UA_BrowseNextResponse browseNextResponse;
    UA_TranslateBrowsePathsToNodeIdsResponse translateBrowsePathsToNodeIdsResponse;
    UA_RegisterNodesResponse registerNodesResponse;
    UA_UnregisterNodesResponse unregisterNodesResponse;
    UA_ReadResponse readResponse;
    UA_WriteResponse writeResponse;
#ifdef UA_ENABLE_HISTORIZING
    UA_HistoryReadResponse historyReadResponse;
    UA_HistoryUpdateResponse historyUpdateResponse;
#endif
#ifdef UA_ENABLE_METHODCALLS
    UA_CallResponse callResponse;
#endif
#ifdef UA_ENABLE_SUBSCRIPTIONS
    UA_CreateMonitoredItemsResponse createMonitoredItemsResponse;
    UA_DeleteMonitoredItemsResponse deleteMonitoredItemsResponse;
    UA_ModifyMonitoredItemsResponse modifyMonitoredItemsResponse;
    UA_SetMonitoringModeResponse setMonitoringModeResponse;
    UA_CreateSubscriptionResponse createSubscriptionResponse;
    UA_ModifySubscriptionResponse modifySubscriptionResponse;
    UA_SetPublishingModeResponse setPublishingModeResponse;
    UA_PublishResponse publishResponse;
    UA_RepublishResponse republishResponse;
    UA_DeleteSubscriptionsResponse deleteSubscriptionsResponse;
#endif
} UA_Response;

/* Do not expose UA_String_equal_ignorecase to public API as it currently only handles
 * ASCII strings, and not UTF8! */
UA_Boolean UA_EXPORT
UA_String_equal_ignorecase(const UA_String *s1, const UA_String *s2);

/********************/
/* Encoding Helpers */
/********************/

/* out must be a buffer with at least 36 elements, the length of every guid */
void UA_Guid_to_hex(const UA_Guid *guid, u8* out, UA_Boolean lower);

#define UA_ENCODING_HELPERS(TYPE, UPCASE_TYPE)                          \
    static UA_INLINE size_t                                             \
    UA_##TYPE##_calcSizeBinary(const UA_##TYPE *src) {                    \
        return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_##UPCASE_TYPE], NULL); \
    }                                                                   \
    static UA_INLINE UA_StatusCode                                      \
    UA_##TYPE##_encodeBinary(const UA_##TYPE *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { \
        return UA_encodeBinaryInternal(src, &UA_TYPES[UA_TYPES_##UPCASE_TYPE], \
                                       bufPos, &bufEnd, NULL, NULL, NULL); \
    }                                                                   \
    static UA_INLINE UA_StatusCode                                      \
    UA_##TYPE##_decodeBinary(const UA_ByteString *src, size_t *offset, UA_##TYPE *dst) { \
    return UA_decodeBinaryInternal(src, offset, dst, \
                                   &UA_TYPES[UA_TYPES_##UPCASE_TYPE], NULL); \
    }

UA_ENCODING_HELPERS(Boolean, BOOLEAN)
UA_ENCODING_HELPERS(SByte, SBYTE)
UA_ENCODING_HELPERS(Byte, BYTE)
UA_ENCODING_HELPERS(Int16, INT16)
UA_ENCODING_HELPERS(UInt16, UINT16)
UA_ENCODING_HELPERS(Int32, INT32)
UA_ENCODING_HELPERS(UInt32, UINT32)
UA_ENCODING_HELPERS(Int64, INT64)
UA_ENCODING_HELPERS(UInt64, UINT64)
UA_ENCODING_HELPERS(Float, FLOAT)
UA_ENCODING_HELPERS(Double, DOUBLE)
UA_ENCODING_HELPERS(String, STRING)
UA_ENCODING_HELPERS(DateTime, DATETIME)
UA_ENCODING_HELPERS(Guid, GUID)
UA_ENCODING_HELPERS(ByteString, BYTESTRING)
UA_ENCODING_HELPERS(XmlElement, XMLELEMENT)
UA_ENCODING_HELPERS(NodeId, NODEID)
UA_ENCODING_HELPERS(ExpandedNodeId, EXPANDEDNODEID)
UA_ENCODING_HELPERS(StatusCode, STATUSCODE)
UA_ENCODING_HELPERS(QualifiedName, QUALIFIEDNAME)
UA_ENCODING_HELPERS(LocalizedText, LOCALIZEDTEXT)
UA_ENCODING_HELPERS(ExtensionObject, EXTENSIONOBJECT)
UA_ENCODING_HELPERS(DataValue, DATAVALUE)
UA_ENCODING_HELPERS(Variant, VARIANT)
UA_ENCODING_HELPERS(DiagnosticInfo, DIAGNOSTICINFO)

/****************************/
/* Legacy Secret Encryption */
/****************************/

UA_StatusCode
encryptSecretLegacy(const UA_SecurityPolicy *sp, void *spContext,
                    const UA_ByteString serverSessionNonce,
                    UA_ByteString *tokenData);

UA_StatusCode
decryptSecretLegacy(const UA_SecurityPolicy *sp, void *spContext,
                    const UA_ByteString serverSessionNonce,
                    UA_ByteString *tokenData);

/******************/
/* ECC Encryption */
/******************/

UA_StatusCode
encryptUserIdentityTokenEcc(UA_Logger *logger, UA_SecureChannel *channel,
                            const UA_SecurityPolicy *sp, void *spContext,
                            UA_ByteString *tokenData,
                            const UA_ByteString serverSessionNonce,
                            const UA_ByteString serverEphemeralPubKey);

/* If the EccEncryptedSecret does not define a certificate, check if the
 * SecureChannel uses the same SecurityPolicy and reuse its context. */
UA_StatusCode
decryptUserTokenEcc(UA_Logger *logger, UA_SecureChannel *channel,
                    const UA_SecurityPolicy *sp, void *spContext,
                    UA_ByteString sessionServerNonce,
                    UA_ByteString *es);

_UA_END_DECLS

#endif /* UA_UTIL_H_ */