Phase 3 PR 71 -- OpcUaAuthType.Certificate user authentication #70

Merged
dohertj2 merged 1 commits from phase-3-pr71-opcua-client-cert-auth into v2 2026-04-19 01:49:30 -04:00
Owner

Summary

Implements the third user-token type (Anonymous + Username already worked). Previously the Certificate branch threw NotSupportedException.

  • New options: UserCertificatePath + UserCertificatePassword.
  • BuildCertificateIdentity loads the PFX via X509CertificateLoader.LoadPkcs12FromFile (non-obsolete .NET 9+ API).
  • Fail-fast validation: empty path → InvalidOperationException with field name; missing file → FileNotFoundException; no private key → clear error explaining why it's needed.
  • UserIdentity(X509Certificate2) ctor wires through to the SDK session-activation payload.

Validation

  • 26/26 OpcUaClient.Tests pass (3 new cert-auth)
  • Tests generate a self-signed RSA-2048 cert on the fly — no static PFX shipped
  • dotnet build: 0 errors

Feature status

All three OPC UA user-token types now supported per driver-specs.md §8: Anonymous + Username + Certificate.

Test plan

  • Missing path rejected with actionable message
  • Missing file rejected
  • Valid PFX loads + TokenType=Certificate
## Summary Implements the third user-token type (`Anonymous` + `Username` already worked). Previously the `Certificate` branch threw `NotSupportedException`. - New options: `UserCertificatePath` + `UserCertificatePassword`. - `BuildCertificateIdentity` loads the PFX via `X509CertificateLoader.LoadPkcs12FromFile` (non-obsolete .NET 9+ API). - Fail-fast validation: empty path → `InvalidOperationException` with field name; missing file → `FileNotFoundException`; no private key → clear error explaining why it's needed. - `UserIdentity(X509Certificate2)` ctor wires through to the SDK session-activation payload. ## Validation - 26/26 OpcUaClient.Tests pass (3 new cert-auth) - Tests generate a self-signed RSA-2048 cert on the fly — no static PFX shipped - `dotnet build`: 0 errors ## Feature status All three OPC UA user-token types now supported per `driver-specs.md` §8: Anonymous + Username + Certificate. ## Test plan - [x] Missing path rejected with actionable message - [x] Missing file rejected - [x] Valid PFX loads + TokenType=Certificate
dohertj2 added 1 commit 2026-04-19 01:49:26 -04:00
Phase 3 PR 71 -- OpcUaAuthType.Certificate user authentication. Implements the third user-token type in the OPC UA spec (Anonymous + UserName + Certificate). Before this PR the Certificate branch threw NotSupportedException. Adds OpcUaClientDriverOptions.UserCertificatePath + UserCertificatePassword knobs for the PFX on disk. The InitializeAsync user-identity switch now calls BuildCertificateIdentity for AuthType=Certificate. Load path uses X509CertificateLoader.LoadPkcs12FromFile -- the non-obsolete .NET 9+ API; the legacy X509Certificate2 PFX ctors are deprecated on net10. Validation up-front: empty UserCertificatePath throws InvalidOperationException naming the missing field; non-existent file throws FileNotFoundException with path; private-key-missing throws InvalidOperationException explaining the private key is required to sign the OPC UA user-token challenge at session activation. Each failure mode is an operator-actionable config problem rather than a mysterious ServiceResultException during session open. UserIdentity(X509Certificate2) ctor carries the cert directly; the SDK sets TokenType=Certificate + wires the cert's public key into the activate-session payload. Private key stays in-memory on the OpenSSL / .NET crypto boundary. Unit tests (OpcUaClientCertAuthTests, 3 facts): BuildCertificateIdentity_rejects_missing_path (error message mentions UserCertificatePath so the fix is obvious); BuildCertificateIdentity_rejects_nonexistent_file (FileNotFoundException); BuildCertificateIdentity_loads_a_valid_PFX_with_private_key -- generates a self-signed RSA-2048 cert on the fly with CertificateRequest.CreateSelfSigned, exports to temp PFX with a password, loads it through the helper, asserts TokenType=Certificate. Test cleans up the temp file in a finally block (best-effort; Windows file locking can leave orphans which is acceptable for %TEMP%). Self-signed cert-on-the-fly avoids shipping a static test PFX that could be flagged by secret-scanners and keeps the test hermetic across dev boxes. 26/26 OpcUaClient.Tests pass (23 prior + 3 cert auth). dotnet build clean. Feature: Anonymous + Username + Certificate all work -- driver-specs.md \u00A78 auth story complete. a79c5f3008
dohertj2 merged commit 3f7b4d05e6 into v2 2026-04-19 01:49:30 -04:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: dohertj2/lmxopcua#70