638 Commits
Author SHA1 Message Date
Niels Beier 37d5404281 fix(plugins): check the context allocation in the default history database 2026-10-17 14:16:12 +02:00
Niels Beier d2d24d8eb7 fix(plugins): check allocations in the history data plugins 2026-10-17 14:16:12 +02:00
Niels Beier 5620d7bd1c fix(plugins): check allocations in the PKCS#11 PubSub policies 2026-10-17 14:16:12 +02:00
Julius Pfrommer f782a38cb6 fix(pubsub): validate TPM key handles and nonce
Require serialized PKCS#11 handles and the specified four-byte key nonce before copying key material into the TPM channel context. This rejects incompatible raw SKS keys and prevents out-of-bounds reads from undersized inputs.
2026-09-18 12:14:58 +02:00
Julius Pfrommer 25aa35db42 fix(pubsub): bound UDP interface-name stack use
Reject interface names that do not fit the transport's fixed input buffer and replace the request-sized stack allocation with a fixed-size array.
2026-09-18 12:14:58 +02:00
Niels Beier 1c1cbbdf8a fix(crypto): use constant-time, length-checked comparison for HMAC/MAC verification
The OpenSSL HMAC-SHA1/SHA256 verify helpers compared the recomputed
MAC against the peer-supplied signature with UA_ByteString_equal(),
which reduces to a plain memcmp(). memcmp() carries no constant-time
guarantee and, on a byte-at-a-time implementation (the norm on the
small-footprint libcs open62541 is routinely built against), returns
as soon as it finds a differing byte -- a timing side channel a
remote peer can use to recover a valid MAC byte-by-byte.

Switch to UA_constantTimeEqual(), already used correctly by every
other symmetric SecurityPolicy (mbedTLS Basic128Rsa15, Basic256,
Basic256Sha256, Aes128Sha256RsaOaep). Since it takes a single length
and reads that many bytes from both buffers, first validate
signature->length against the expected MAC length, mirroring the
pattern used by the project's mbedTLS RSA policy Verify functions.
The digest length is fixed by the algorithm and policy, not attacker
data, so this early-return introduces no new timing side channel.

Internal Vulnerability Advisory: open62541-SA-2026-0038
Co-authored-by: Luigi Colluto <gigioneggiando@users.noreply.github.com>
2026-09-15 20:31:48 +02:00
Niels BeierandLuigi Colluto b6bd2cf88d fix(pubsub): fix OOB read/write and truncation in AES-CTR TPM en/decrypt
encrypt_sp_pubsub_aes128ctr_tpm/decrypt_sp_pubsub_aes128ctr_tpm and their
AES-256-CTR counterparts computed the block-aligned processing size
(sizeToEncrypt/sizeToDecrypt) by rounding data->length up to the next
16-byte boundary, but stored the result in a CK_BYTE. Two distinct bugs
followed from this:

- For a data->length whose rounded-up value exceeds 255, the 8-bit value
  wraps around, so far fewer bytes than intended are processed while the
  function still returns UA_STATUSCODE_GOOD.
- For any data->length that is not itself a multiple of 16, the rounded-up
  size is larger than the caller's actual buffer. The PKCS#11 update calls
  then read block-sized chunks directly from data->data past its end, and
  the final loop that copies the result back writes that same rounded-up
  size into data->data, overflowing the caller's allocation.

AES-CTR is a stream cipher and never needs block-aligned input. Fix this
by processing exactly data->length bytes throughout, using size_t/CK_ULONG
for all lengths instead of CK_BYTE: each PKCS#11 update call is chunked at
MAX_ENCRYPTION_SIZE bytes with a shorter final chunk when data->length is
not itself a multiple of it, operating on the caller's buffer directly
with no rounding, no padding, and no risk of the output exceeding the
caller's allocation.

Co-authored-by: Luigi Colluto <gigioneggiando@users.noreply.github.com>

Internal Vulnerability Advisory: open62541-SA-2026-0033
2026-09-15 20:10:23 +02:00
Niels Beier 7a08139590 fix(historydata): prevent UAF in memory backend range-limited history reads
UA_DataValue_backend_copyRange() performed a shallow memcpy of the
source UA_DataValue before attempting the range copy. Because the
destination's UA_Variant fields were not reinitialized first, a
failing UA_Variant_copyRange() (for example when the client-supplied
indexRange exceeds UA_MAX_ARRAY_DIMS) left the destination value as an
uninitialized alias of the backend-owned storage instead of an
independent copy.

copyDataValues_backend_memory() also discarded the status code from
both UA_DataValue_backend_copyRange() and UA_DataValue_copy(), so the
aliased, partially-copied value was still counted as a successful
result and forwarded to the HistoryRead response. Freeing that
response later released the backend's live storage, leaving the
backend with a dangling pointer that was dereferenced on a subsequent
HistoryRead.

Reinitialize the destination variant before the range copy and clear
it again on failure, mirroring the safe pattern already used by
UA_DataValue_copyRange(). Propagate copy failures out of
copyDataValues_backend_memory() immediately instead of counting a
failed entry as provided.

Internal Vulnerability Advisory: open62541-SA-2026-0021
Co-authored-by: gff-cw <gff-cw@users.noreply.github.com>
2026-09-04 13:20:06 +02:00
Niels Beier f828c6051d fix(historydata): validate and cap continuation point skip in HistoryRead
In getHistoryData_service_default(), the outer continuation point encodes
a skip count that was read directly from client-controlled bytes without
validation. Two independent arithmetic errors could cause a heap-buffer-
overflow in the subsequent backend copy call:

1. When skip > _resultSize, the subtraction `_resultSize - skip` wraps
   around in size_t, producing a very large value. After clamping to
   maxSize, the allocation is correct, but the wrapped large skip is
   still used to recompute valueSize for the backend call.

2. When the reconstructed valueSize exceeds the number of entries actually
   allocated in outResult, copyDataValues() writes beyond the end of the
   result array (heap-buffer-overflow write).

Fix both issues in getHistoryData_service_default():
- Reject continuation points whose skip value exceeds the computed result
  set size, returning UA_STATUSCODE_BADCONTINUATIONPOINTINVALID.
- After computing valueSize, cap it to the remaining allocated capacity in
  outResult so the backend cannot be instructed to write past the buffer.

Internal Vulnerability Advisory: open62541-SA-2026-0027
2026-08-14 10:12:35 +02:00
Niels Beier 9c1636a232 fix(server): Cap default outstanding PublishRequest count per session
The default server configuration zero-initialises
maxPublishReqPerSession, which disables the per-session cap on
outstanding PublishRequest entries. A remote client that is allowed
to create a session and a subscription can therefore send an
unbounded number of PublishRequest messages, each of which allocates
a UA_PublishResponseEntry and appends it to the session's publish
queue. The resulting monotonic heap growth causes process memory
exhaustion and a denial of service.

Set a safe finite default of 512 outstanding PublishRequests per
session in setDefaultConfig() so that the cap is enforced out of the
box, while still allowing deployers to override it.

Internal Vulnerability Advisory: open62541-SA-2026-0010
Co-Authored-By: keyme <kmm2003@users.noreply.github.com>
2026-07-09 14:10:23 +02:00
Marvin Gnad 51ff6593ec fix(plugin): fix namelist allocated from scandir not freed
(cherry picked from commit bcb02196fb)
2025-12-09 11:20:38 +01:00
Julius Pfrommer 1aceacf57f fix(plugins): Use the session parameters feature instead of storing data in the SessionContext
This fixes #7361
2025-11-05 11:34:01 +01:00
Julius Pfrommer 59d7cc5f21 fix(plugins): Pacify a clang warning in ua_pki_mbedtls.c 2025-10-10 15:33:29 +02:00
Julius Pfrommer 68142484a3 feat(plugins): Disable revocation lists checks in ua_pki_openssl.c if zero crl are loaded
Avoid breakage for users of the 1.3 release family but still log a warning.
2024-11-23 21:57:36 +01:00
Julius Pfrommer efbaac086e feat(plugins): Disable revocation lists checks in ua_pki_mbedtls.c if zero crl are loaded
Avoid breakage for users of the 1.3 release family but still log a warning.
2024-11-23 21:57:36 +01:00
Julius Pfrommer 80bbdd4170 fix(plugins): Return detailed status codes for revocation checks in ua_pki_openssl.c 2024-11-23 21:57:36 +01:00
Julius Pfrommer 486a65ee10 fix(plugins): Also consider the trustlist to find issuers in ua_pki_openssl.c 2024-11-23 21:57:36 +01:00
Julius Pfrommer 2e516fd7bd fix(plugins): Return detailed status codes for revocation checks in ua_pki_mbedtls.c 2024-11-23 21:57:36 +01:00
Julius Pfrommer 3ebc92e66a fix(plugins): Also consider the trustlist to find issuers in ua_pki_mbedtls.c 2024-11-23 21:57:36 +01:00
Julius Pfrommer ff7dc78d2d refactor(plugins): Small cleanups in ua_pki_mbedtls.c 2024-11-23 21:57:36 +01:00
Julius Pfrommer cd9088a079 refactor(plugins): Refactor out mbedtlsSameBuf to compare mbedTLS buffers 2024-11-23 21:57:36 +01:00
Julius Pfrommer db91b23259 fix(plugins): Manually classify certificates as CA for OpenSSL
Replace the builtin method with manual classification. We now require
the KU_CRL_SIGN flag to detect a CA. Before we rejected the leaf
certificates generated by some vendors.
2024-10-22 23:50:15 +02:00
Julius Pfrommer 0a48591990 fix(plugins): Disable the Basic128Rsa15 and Basic256 SecurityPolicy 2024-10-03 13:47:11 +02:00
Julius Pfrommer f9d4c16310 fix(plugins): More thorough validation that the issuer is a valid CA 2024-10-02 18:01:34 +02:00
Julius Pfrommer c63520c407 refactor(plugins): Use the same certificate verification logic for mbedTLS and OpenSSL
Walk the tree to find a complete chain of unrevoked and current
certificates.  The chain must end in a self-signed certificate.
Then, on the "way down", check that at least one certificate
in the chain is trusted.
2024-09-27 21:18:38 +02:00
Julius Pfrommer 01086d6de8 refactor(plugins): Refactor mbedTLS certificate verification to include intermediate steps 2024-09-26 23:36:21 +02:00
Julius Pfrommer 19ecf3e562 refactor(plugin): Manual OpenSSL certificate verification steps
The previous certificate verification relied on many OpenSSL internals
and a forest of feature-flags.  The new code is about the same size and
makes the certificate verification steps explicit.

The only downside is that we no longer auto-retrieve revocation lists if
a distribution point is defined in a CA certificate. But revocation is
handled by a GDS in OPC UA. And we don't want our certificate
verification to do synchronous HTTP calls in the background.
2024-09-22 23:49:24 +02:00
Julius Pfrommer ee79096b65 fix(plugin): Always clean up the previously configured certificate verification plugin 2024-09-22 23:49:24 +02:00
Julius Pfrommer af1abb2e83 refactor(plugins): Better cleanup of the OpenSSL CertificateVerification plugin 2024-09-22 23:49:24 +02:00
Noel Graf f199580223 fix(plugin): Proper error handling when checking parent CRL for the mbedTLS backend 2024-09-16 17:27:51 +02:00
Christian von Arnim f4af493b57 fix(core): LibreSSL 3.5
(cherry picked from commit 35939a5b68)
2024-09-16 17:27:51 +02:00
Romain Gauci 9b6848a7e8 fix(plugin): Proper error handling when checking all CRLs
If a chain of Certificate Authorities (CAs) longer than one is present,
all CRL checks on the additional CAs were bypassed. This resulted in the
potential acceptance of certificates that have been revoked or have
expired CRLs.
2024-09-11 10:25:57 +02:00
soekkle 317819b7d3 fix(plugin): Avoid memmory read access errors (#6688)
Check for null pointer befor passing then into a openssl function.
2024-09-10 09:07:58 +02:00
Julius Pfrommer 539e1b305a Merge remote-tracking branch 'origin/1.2' into merge_12_13_10 2023-10-06 11:39:20 +02:00
Alexander Bluhm f4b481276a feat(plugin): allow custom password validation
Username password validation in access control plugin allows only
passwords stored in plaintext.  Add a callback to implement custom
validation.  This allows salted password hashes and timing safe
comparison in the server.  Furthermore remote validation could be
implemented.  The new function UA_AccessControl_defaultWithLoginCallback()
calls existing UA_AccessControl_default() and after that installs
the given UA_UsernamePasswordLoginCallback with context.
2023-09-28 12:50:19 +02:00
Jörg Schüler-Maroldt 55f486e2f5 fix(plugins): Two security fixes for OpenSSL uncovered by MSVC (#6009)
* In UA_CertificateVerification_VerifyApplicationURI()
set initial subjectURI to UA_STRING_NULL, may be no urn entry in certificate

* Fix problem, if UA_OpenSSL_LoadCertificate() fails in UA_ChannelModule_New_Context()
2023-09-11 13:21:29 +02:00
Alexander Bluhm df733d0f1d fix(plugin): Declare log constants static
The constant string arrays logLevelNames and logCategoryNames are not
exported neither in header include nor in dynamic library.  But they
appear in static libopen62541.a library and my create conflicts.
Declare these symbols static to keep them local in ua_log_stdout.c .
2023-08-09 15:58:56 +02:00
Julius Pfrommer 2e9959fed8 refactor(plugin): Use the architecture UA_Lock for stdout logging
cherry-pick 3075db12b7
2023-06-30 09:10:41 +02:00
StalderT dc61a5a8cf fix(plugin): Fix gcc 12 warning in pki plugin 2023-06-16 00:01:32 +02:00
Julius Pfrommer 9e86eedb43 fix(plugin): Forward rng when calling mbedtls_pk_decrypt
The issue was reported in #5631.
2023-04-05 14:13:56 +02:00
Julius Pfrommer ec55929612 fix(plugin): Fix removal of AllowAll cert validation for OpenSSL 2022-11-14 11:57:38 +01:00
Bin Lan eedfdbf31e feat(plugin): Add OpenSSL 3.0 support (#5349)
* Add OpenSSL3.0 support

This change set adds a new function UA_OpenSSL_RSA_Key_Size() to get
the RSA key size, re-writes the function
UA_Openssl_RSA_Private_Decrypt() by using the high level APIs of
OpenSSL3.0, add a new function UA_RSA_Generate_Key() to generate
a RSA key.

No build warning with OpenSSL3.0 and OpenSSL1.1.1f.

* Build & Test with OpenSSL3.0 in Ubuntu22.04
2022-11-14 11:51:56 +01:00
Julius Pfrommer 6674768d7c Merge remote-tracking branch 'origin/1.2' into merge_12_13_7 2022-11-14 11:51:51 +01:00
Julius Pfrommer b6ab8d3b71 fix(plugin): Disable padding by OpenSSL (is done internally)
This lead to OpenSSL mistakenly writing behind the buffer length in some
cases.
2022-11-14 07:28:49 +01:00
Julius Pfrommer 106cd61ad9 fix(plugin): Reject all certificates for empty trust-list 2022-11-14 07:28:49 +01:00
Julius Pfrommer 1d6aa03333 fix(plugin): Fix warning for use of OPENSSL_API_COMPAT 2022-11-14 07:28:49 +01:00
Bin Lan 3a7067a174 feat(plugin): Add OpenSSL 3.0 support (#5349)
* Add OpenSSL3.0 support

This change set adds a new function UA_OpenSSL_RSA_Key_Size() to get
the RSA key size, re-writes the function
UA_Openssl_RSA_Private_Decrypt() by using the high level APIs of
OpenSSL3.0, add a new function UA_RSA_Generate_Key() to generate
a RSA key.

No build warning with OpenSSL3.0 and OpenSSL1.1.1f.

* Build & Test with OpenSSL3.0 in Ubuntu22.04
2022-11-14 07:28:49 +01:00
Julius Pfrommer 825d847b31 fix(plugin): Fix crash in OpenSSL when loaded with an empty certificate 2022-11-14 07:28:49 +01:00
Michał Tyndel 3fc6870a9d fix(pubsub): Set correct block counter for aes-ctr encryption
According to part 14 (7.2.2.4.3.2) the initial value of AES128 and AES256 encryption block counter should be set to 1, not 0.
2022-11-03 12:17:25 +01:00
Joe Riemersma 4091c86e34 fix(core): DataValue statuscodes checks ignore additional information bits (#5375)
* fix(core): DataValue statuscodes checks ignore additional information bits

* fix(core): Update UA_StatusCode_name to use UA_StatusCode_equal

* fix(core): rename UA_StatusCode_equal to UA_StatusCode_isEqualTop and update function docs

* fix(core): changed statuscode message invlaid status code value to real invalid statuscode

* fix(core): fix windows clang build
2022-10-20 08:38:46 +02:00