* New certificate and secrete abstraction with certificate infrastructure and certificate/secret stores.
* leak testing for certificate resources to validate new ref counting in every test assembly
* Migration guide updated and documentation added for all
* Remove IDisposable from Nodestate and UserIdentity.
* UserCertificateTokenHandler now just points into certificate registry/stores, no dispose required
* Fix CA2000 warnings and cleanup of other diagnostics, increase warning levels in .editorconfig
* Add source-generated NodeManagers and fluent wiring API
Adds a fluent INodeManagerBuilder API for wiring per-node callbacks and a model-aware source generator that emits a partial CustomNodeManager2 plus an INodeManagerFactory for each design file.
Opt-in is per class via [Opc.Ua.Server.Fluent.NodeManager] on a partial class (recommended) or project-wide via the ModelSourceGeneratorGenerateNodeManager MSBuild property (legacy). The attribute supports NamespaceUri / Design selectors for multi-design projects and a GenerateFactory toggle. Diagnostics MODELGEN010 / MODELGEN011 surface unmatched bindings and non-partial classes.
Adds the ConsoleBoilerServer NativeAOT sample driving the new pipeline end-to-end with Microsoft.Extensions.Logging.Console and updated docs in Docs/SourceGeneratedNodeManagers.md.
* Add BoilerServer AOT smoke test
Verifies the source-generated Boiler.BoilerNodeManagerFactory loads
the boiler address space, registers its namespace, and dispatches the
fluent OnRead callbacks wired in BoilerNodeManager.Configure.cs.
All 3 new tests pass in JIT mode and against the NativeAOT-published
binary; total Aot.Tests suite: 71/71 pass.
Concrete sub-types of the abstract OptionSet DataType (i=12755, e.g. AccessRights, CarExtras, OptionSetBase) were silently skipped by ComplexTypeSystem.LoadBaseStructureDataTypesAsync when only an EnumDefinition or OptionSetValues property was available. This change registers them with a new runtime class Opc.Ua.Encoders.OptionSet that reuses the generated Opc.Ua.OptionSet wire format (Value/ValidBits ByteStrings) and self-registers via IEncodeableType.
Key changes:
- New Stack/Opc.Ua/Types/OptionSet.cs with EnumDefinition-driven bit accessors (by name and index), GetSetFieldNames helper, and a fixed ByteLength derived from the highest declared bit per OPC UA Part 3 paragraph 8.40 / 3.2.8. SetBit throws ArgumentOutOfRangeException outside that range and always materializes Value/ValidBits to the fixed length.
- New AddOptionSetType entry point on IComplexTypeBuilder (source-breaking addition for custom implementations); DefaultComplexTypeBuilder implements it. The Reflection.Emit ComplexTypeBuilder throws NotSupportedException.
- ComplexTypeSystem detects OptionSet descendants via a HasSubtype walk and resolves the EnumDefinition from DataTypeDefinition or the OptionSetValues property fallback before the old skip path.
- Removed stale V1.04 OptionSet limitation remark from ComplexTypeSystem.
- 10 unit tests in Tests/Opc.Ua.Client.Tests/ComplexTypes/DefaultOptionSetTests.cs covering factory registration, bit accessors, binary round-trip via ExtensionObject, hand-crafted Part 6 wire format, Clone/CreateInstance semantics, and the ByteLength invariant.
- Live-verified against opc.tcp://DESKTOP-BGFJS91:48010 (UA C++ SDK demo): AccessRights/CarExtras/OptionSetBase now appear in the registered custom-type list; no skip-log entries; LoadAsync(throwOnError:true) returns true.
- Docs/ComplexTypes.md Known Limitations reworded; Docs/MigrationGuide.md gains an OptionSet DataType support subsection.
UInteger-backed OptionSet DataTypes remain intentionally opaque (carried as their unsigned integer in a Variant).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* merged security changes
* Tailor SecurityPolicyUri for format expected in s_securityPolicyUriToInfo
* Enhance security policy handling and key computation logic
* Merge SecurityEnhancements.
* Add support for SessionTransferToken. Removed obsolete SoftwareCertificate code.
* Fix NonceLength for None.
* Add support for RSA_DH, more fixes from IOP testings.
* Finish implementation of SecureChannelEnhancements.
* Rename EccUtils.cs to CryptoUtils.cs
* Address feedback from reviewers.
* Fix CoPilot flagged spelling errors.
* Rename EccUtils to CryptoUtils
* Update version from 1.5.378-preview to 1.5.378
* Fix unit tests.
* Allow SignatureData.Algorithm to be NULL or Empty.
* Fix issue with BrainPool_p256r1_ChaChaPoly
* Fix RSA_DH_AesGcm
* Fix OSC/padding by deriving HMAC keys, tightening symmetric size math, and correcting ECC_brainpoolP384r1/Basic128Rsa15 IV, signature, padding, and nonce parameters.
* Policies without asymmetric encryption (ECC) return the plaintext when encrypting user tokens; this prevents null payloads from causing BadIdentityTokenInvalid.
* Reserve outer CBC padding for avoiding SymetricEncryptAndSign->AddPadding to overwrite next fields (signature)
* Nonce stored as byte array in SessionConfiguration; Sesion snapshot restores ServerNonce and reconstructs ECC ephemeral key Nonce from bytes and policy
* Added _AesGcm and _ChaChaPoly variants to BuildSupportedSecurityPolicies() for all six ECC certificate types (nistP256, nistP384, brainpoolP256r1, brainpoolP384r1, curve25519, curve448) to SecurityConfiguration. Added Sign and SignAndEncrypt endpoints for the four ECC AesGcm/ChaChaPoly policy pairs (nistP256, nistP384, brainpoolP256r1, brainpoolP384r1) to ServerFixture.
* make ephemeralKeyPolicyUri nullable
* GenerateSecret also for NET7 and NET8
* Adjust Basic128Rsa15 policy properties for backword compatibility
* Exclude unsuported AEAD policies from .NET Framework client tests
* Addapt to new changes (still build fail)
* Addapt code to make it compile
* Fixed failing build on net48 (by ignoring potential null ref which is not reported on other newer targets)
* Preserve the certificate reference in Clone() so copied handlers can still sign
* Remove extra code and addapt to existing master configuration settings
* Filter *_AesGcm and *_ChaChaPoly security policies based on actual runtime support, so unsupported AEAD policies are not advertised or selected on older frameworks
* Expand ECC/RSA policy test coverage and keep Basic128Rsa15 nonce length backward-compatible
* Fix ReconnectSessionOnAlternateChannel _AES and _ChaCha policies
* Fixed IgnoreIfPolicyNotAdvertised so it now fetches endpoints on-demand (instead of relying on Endpoints being preloaded by earlier tests), which avoids false ignores when running tests directlyy
* Merge with commit 5e627f2ca1 from secure-channel-enhancements-2025-11 branch
* minor log mesatge formating
* Fix ClientLockoutTests
* Add ServerFixture policies upfront only if framework and runtime capability supports them
* A few cosmetic/config changes as review sugested
* Moved the session/security handling from StandardServer into a dedicated helper
* use X509IdentityTokenHandler from secure-channel-enhancements-2025-11
* Removed unused Opc.Ua.Types.UnitTests.csproj
* test(client): fix Basic128Rsa15 reconnect token-policy coverage
Advertise an explicit Basic128Rsa15 user token policy in the test fixture and tighten the reconnect test preconditions for non-advertised policies.
* test(client): fix session nonce persistence test helpers
Replace the generic reflection helpers in SessionTests with explicit client/server nonce accessors that match the actual field types.
Add a short Session comment to explain why client and server nonces currently use different representations.
* Merge branch 'master' into secure-channel-enhancements-2025-11-merge5
Merge with latest master and fix conflicts.
* Removed unused Opc.Ua.Types.UnitTests.csproj
* test(client): fix Basic128Rsa15 reconnect token-policy coverage
Advertise an explicit Basic128Rsa15 user token policy in the test fixture and tighten the reconnect test preconditions for non-advertised policies.
* test(client): fix session nonce persistence test helpers
Replace the generic reflection helpers in SessionTests with explicit client/server nonce accessors that match the actual field types.
Add a short Session comment to explain why client and server nonces currently use different representations.
* Build fixes
* Fix build
* update
* Minor updates
* Fix tests
* Add code to check all Endpoints.
* Update Design files to 1.05.7
* Run code fixers, add missing docs
* Fix build
* Revert removal of using
* Increase build timeout
---------
Co-authored-by: mrsuciu <Mircea-Adrian.Suciu@Softing.com>
Co-authored-by: Randy Armstrong <randy@sparhawksoftware.com>
* make most ptojects aot compatible
* Remove newtonsoft
* Migrate all projects from Mono.Options to System.CommandLine 2.0.5
* Fix array clone
* Replace serializers for storage using new attribute driven type geberator
* Add new AOT integration tests covering all functional areas
* Documentation updates
This pull request modernizes the OPC UA .NET codebase and tests, removes .NET Standard 2.0 support from certificate/security code, and updates test code to use C# 12 and .NET 8+ features for clarity and maintainability.
- Certificate and BouncyCastle interop files (e.g., CertificateBuilder.cs, X509Extensions.cs, X509SignatureFactory.cs) are refactored to drop NETSTANDARD2_0 support and use modern .NET APIs and conditional compilation.
- Test code across the codebase is updated to use default, strongly-typed Parse methods, collection expressions, and improved async/await patterns.
- Exception handling and assertions in tests are modernized, and test method naming is made consistent with Async suffixes.
- The project and build files are updated to clarify Roslynator analyzer usage and remove obsolete netstandard tags.
- General code and test cleanup includes improved null safety, type safety, and removal of deprecated or unused code.
* Add per-namespace NodeSet2 export and CLI option
Implemented ExportNodesToNodeSet2PerNamespaceAsync in ClientSamples to export nodes into separate NodeSet2 XML files per namespace, excluding OPC Foundation companion specs. Added a helper for safe filename generation. Introduced a new -e/--export command-line option in Program.cs to trigger this export after node fetching. Also added System.Xml.Linq import for potential XML handling.
* Add NodeSetExportOptions for flexible NodeSet2 export
Introduce NodeSetExportOptions to control which attributes and values are exported to NodeSet2 XML, with Default, Minimal, and Complete presets. Overload ExportNodesToNodeSet2 to accept these options and update internal logic accordingly. Update CreateNodeState to honor export preferences. Add comprehensive unit tests for all export modes and ensure backward compatibility. Update ClientSamples to use Complete export mode.
* Refactor NodeSet export options for minimal default output
- Change ExportValues default to false; values only for Complete option
- Remove ExportUserAccessLevel and ExportMethodDeclarationId options
- Always export MethodDeclarationId; export UserAccessLevel only if different from AccessLevel
- Remove Minimal option; Default now produces minimal schema output
- Update export logic and tests to reflect new option semantics
- Rename and revise unit test to verify new default and complete behaviors
* Remove unused BitVector32 import
* Add ExportUserContext option to NodeSet2 export
Introduce ExportUserContext to NodeSetExportOptions, allowing selective export of user context attributes (UserAccessLevel, UserExecutable, UserWriteMask, UserRolePermissions) in NodeSet2 files. Update export logic to honor this option and add unit tests to verify correct behavior. This enhances flexibility and control over exported user-specific metadata.
---------
Co-authored-by: Marc Schier <marcschier@users.noreply.github.com>
This change adds a **new Opc.Ua.Types** nuget that contains core types that do not rely on generated code. Why the name? Because almost all code that was in the Types subfolder is part of it, and because we do not want to change the name of the Opc.Ua.Core nuget/assembly because code relies on it. Any other name like base or bootstrap felt out of place due to the current structure already defining the name "types". Key design is to depend on only a small set of libraries with limited transitive dependencies, that includes hashcode, logging.abstraction, and for non standard20 builds System.Text.Json (needed for localizedText mul parsing). Also, key is to support .netstd 2.0 to support source generators and to allow removal of EEC_SUPPORT defines by removing std2.0 from core and all libraries.
The changes are mostly restructuring, and thus small but contain some key changes:
- **Status code** struct now comes with a Symbol field, which is used to carry symbols in case the code is not generated. Currently (until generated) the status code struct must be manually created with a symbol or the ToSymbolicId extension must be called in the core project. Future will generate Status code constants just like NodeId that contain the symbol which also removes the reflection-based lookup. Several tests needed to be adjusted as they checked the status code symbol strings instead of the code.
- **Core identifiers** are copied as they were needed for code to compile, that includes attributes, a subset of status codes and node identifiers. These will never change so no need to generate them.
- The types folder now contains **encoders**, except for json which is still in core. Once the json encoder is ported to system.text.json it will also be included and Newtonsoft.Json dropped as dependency (-> #3329).
- Since types relies on **IOperationContext** and **ISystemContext**, and these export IUserIdentity which relies on crypto, these were split and extended in core with ISessionOperationContext and ISessionSystemContext, which mean changes to ServerSystemContext and introduction of SessionOperationContext and SessionSystemContext classes that extend OperationContext and SystemContext. Some runtime checks in the server are therefore needed to get at the session and auth info, however, those are anyway optional fields and are not on the critical paths, and thus a type check is in order (and was done in the past already, but against OperationContext class).
- **Manifest resources** are now split between Core (nodeset zip, some generated resoures) and Types (built in bsd/xsds). This needs to be revisited later if the bsd/xsd need to be regenerated during type generation. Note that the embedded resource names changed as a result. Since these are only used internally and do not constitute public API this feels reasonable vs duplication of resources in 2 assemblies.
- Reflection however now needs to load not just the built in **encodeables** from Opc.Ua.Types assembly, but also the generated encodeables from Opc.Ua.Core assembly. For this a new helper Utils method was added to get the Core assembly when linked against Opc.Ua.Core otherwise null.
- Whatever utils methods needed to be split out into the new Opc.Ua.Types assembly, they are now in **CoreUtils** static class in Opc.Ua.Types, and Utils.xxxx forwards to them to ensure minimal changes. Later we would want to obsolete them in favor of CoreUtils, although it might make sense to split them again into domain specific utilities, such as networking, files, etc
* Refactor string usage for secrets (#394)
Strings are immutable and the lifetime of secrets can not be controlled.
Use byte[] or char[] instead of strings for secrets, which can be erased
after use.
* Clear pw
---------
Co-authored-by: Martin Regen <7962757+mregen@users.noreply.github.com>
* Enable Durable Subscriptions (#9)
* [Server] Durable Subscriptions (#2683)
* Implement a system test for DurableSubscriptions (#2839)
* Client Side
Co-authored-by: ALTERNATE-DEV\Archie <archie@dreamsandadventures.ca>
* make a static Method CalculateRevisedQueueSize
* Adress review feedback
* fix FilterRetainTests
* Add MonitoredItem Id to Queues
Use NodeIdDictionary where possible
- Port support for ECC NIST/Brainpool profiles from prototyping_ecc branch
- Implement CertProvider to load certs per connection / profile
- Backward compatibility of configuration for existing apps
- SecurityConfiguration specifies app cert types for each profile
- Autodetect the ECC support for brainpool/nist based on platform (mac OS 10 doesn't support brainpool)
- ECC supported on net48 / net5.0 / net 6.0 / netstandard2.1
- ECC supported on windows / linux / macOS (brainpool not < macOS11)
- Self signed certs for each profile are created on start similar to RSA
- RSA only profiles are supported on .NET standard 2.0
Co-authored-by: Martin Regen <mregen@microsoft.com>
Added a new method ManagedBrowse to the UA client, which takes care of calling browse next after calling browse, when necessary. It also handles the status codes BadNoContinuationPoint and BadInvalidContinuationPoint.
Added support for the new method in ISession, TraceableSession, Session and SessionAsync.
Use the new methods in the NodeCache and other API that use browse (FetchRefrences etc).
Added unit tests which verify correct behavior of the new methods.
- Fix the UserIdentity constructor to load the private key of a provided certificateIdenifier.
- make UserIdentity constructor throw a ServiceResultException when a Certificate with no private key is specified.
- extend console reference client with two new parameters:
-uc Thumbprint of a user certifiate located in the TrustedUserCertificatesStore
-ucp Password of the private key of the user certificate
- add documentation for console reference client
Fix that if a socket is closed, new service calls are queued and a new channel is established without reconnect / activate.
Add some logic which ensures that a BeginConnect operation is only started if a valid service call is queued first.
The activate is prepared by the session reconnect handler which may take some time to respond. Until then, all other service fail immediately with BadNotConnected.
To detect socket failures earlier, the PublishRequest and KeepAlive send are also hooked up to the KeepAliveError to trigger a reconnect. To disable the keep alive timing calcualtion, an additional variable tracks the statuscode of the last error to set KeepAliveStopped to true.
* Added MaxChannelCount and detect and cleanup "stale" channels based on ChannelLifetime
* Add Environment.TickCount as time reference
* Set a socket backlog value to avoid socket open overflow
* Added a ChannelKeepAlive to signal when a session is still active
* Add options to console client to leak channels and run connect loop forever
Co-authored-by: Martin Regen <mregen@microsoft.com>
- improve various log messages, comments etc.
- multiple internal improvements in naming convention handling of async functions
- add FetchSuperTypesAsync
- replace new UTFEncoding() with Encoding.UTF8 singleton
- With exponential backoff enabled, a KeepAlive calling `BeginReconnect` could retrigger the timer in a way that a reconnect would never occur.
- Throttle `ISession.BeginPublish` on `BadTooManyOperations` error.
- Add reverse connect option to console client to test reconnect with reverse connect manager.
- null events in session on dispose to suppress spurious events.
- mark `TransferSubscription` service calls obsolete to avoid accidential use by applications.
- for reverse connection testing of session reconnect handler, add options for no security and reverse connect endpoint to console client
- Deprecate support for Nuget package support of .NET Framework 4.6.2
- Bump sample applications to 4.8
- update some copyright headers / supporting files (editorconfig etc.)
- fix a few warnings
- fix an issue with `SessionReconnectHandler`, in certain combination of reconnect period and exponential backoff the .NET sample app never reconnected.
- due to the new `MinPublishRequestCount` property publish requests are being sent after reconnect even if no subscription is active
- Improve sample code to show how to dispose the old session after reconnect
Currently the session reconnect requires to create and destroy the object and to lock the operation in the client code.
The refactored version is backward compatible but allows for a single instance to handle reconnects during the lifetime of the client. In addition no more locking is necessary in the client code.
- exponential backoff is enabled by using a constructor `new SessionReconnectHandler( true, 30000);` which would set the maxReconnectPeriod` to 30000ms. The backoff period is doubled after every unsuccessful request.
- a 10% random jitter is added to every timer update.
- The `public virtual int JitteredReconnectPeriod(int reconnectPeriod)` and `public virtual int CheckedReconnectPeriod(int reconnectPeriod, bool exponentialBackoff = false)` can be overloaded to implement custom jitter and backoff implementations.
- A new `ISession.MinPublishRequestCount` property can be set to enforce a minimum number of active publish requests. Default behavior is one publish request per subscription. It can help for low latency high frequency publish intervals.
- A new `PublishSequenceNumbersToAcknoledge` event is implemented which allows to defer ack of sequence numbers until fully processed by the client.
All new methods/properties ar not breaking changes and by default there is no behavior change, all existing code should work and compile aginst the update flawlessly.
- A bugfix in the reconnect handler, when a server changed the application certificate the reconnect ends up in an endless loop, because the `EndpointDescription` is not updated. The fix updates the endpoint from the server if a `BadSecurityChecksFailed` error os returned and then tries to reconnect with a new session.
- Add environment variables as parameter to support docker hosting where command line parameter are not available
- bump some Nuget packages
- only warn on cert validation error on startup, e.g. when the CRL becomes outdated allow to start and print warning.
- Let GetEndpoints return endpoints which match the DNS name used. DNS names must be specified as alternate hostnames in the configuration.
Improvements for complex types.
- Support to encode/decode complex type structures with multidimensional arrays.
- Perf improvements for type loader using new NodeCache fetch multiple interfaces.
- DataTypeDictionary validation when dependencies are used.
- interface for complex type resolver, to build custom types in code.
- improvements of console client to demonstrate browse/read of custom values
+++ Breaking changes +++
IDecoder interface change of the `ReadArray` method
- Return type is now `Array` for all types of arrays. Previously the method returned an array for 1-dim and a `Matrix` type for multidimensional arrays. In addition the convention in generated code is to use `Collection` for all 1-dim arrays, and so was built the `BaseComplexType`. The new convention is to expose the native `Array` type from a complex type, in all cases, hence the return type of `ReadArray` was changed to reflect that for a consistent programming model.
- `ReadArray` has a new parameter `systemType` to efficiently read encodeable types. Previously the `Type` of an encodeable was determined by the encodingid and lookup in the type factory, even when the Type is already known by the caller. The 'old' style is still supported.
- `ReadArray` supports to read encodeable type arrays which are directly encoded in structures. These arrays differ from standard encoding of arrays and they are handled when `BuiltInType.Null` is used as parameter.
- set `KeepAliveTimeout` default back to 5s, was unintentionally set to 50s in 368 release
- fix a bug that duplicate subscriptions were created after reconnect when transfer succeeds.
- add a property to enable subscription transfer in reconnect, set `Session.TransferSubscriptionsOnReconnect=true` to enable, IOP issues may not allow to use it with some servers.
- add a `SessionReconnectHandler(true)` constructor to support reconnect abort, if the connection recovers before reconnect timer called. If the new constructor is used, its a breaking change: Needs check of `Session` property in Reconnect handler callback, if aborted `Session==null`.
- Reduce warning log output if server timestamp > client time.
- Add handling when subscriptions can not be transferred, e.g. when false user credentials or no security prevent transfer.
- Improve the reconnect timer handling by using `OperationLimit` in reconnect.
- Add sample for `SessionReconnectHandler` in console client.
- Seperate session sample code from `UAClient`.
- Tested on popular demo servers of various SDK vendors.
- Fix Winforms ref client
- Only an issue if the configuration does not specify the security policy uri for anonymous token
- If the config does not specify the security policy, for anonymous user token the security profile Basic256Sha256 was chosen.
- This setting requires for the client to trust the server certificate if it tries to connect with security None, may cause IOP issues when no security is chosen and encryption is required for the anonymous user token.
- support for Microsoft.Extensions.Logger.ILogger in Opc.Ua.Core as the new logging interface
- backward compatible with config and TraceEvents
- new API Utils.SetLogger allows to set ILogger
- updated Console samples to demonstrate ILogger support with Serilog
- support for EventSource logging
- see Docs/Logging.md for more info
* Adds proper TPL usage, decouples dependencies on Console and ClientBase, and uses string interpolation versus String.Format.
* Renames private members to standard naming convention.
* implement transport binding factory
* split https transport into seperate nuget package
* new Opc.Ua.Binding.Https assembly
* Https binding is loaded on demand, if available
* reduce core dependencies to kestrel and others
fixes#600