Skip to content

fix(plc4j/opcua): correct unencrypted username token encoding - #2828

Open
dongxuelian2 wants to merge 1 commit into
apache:developfrom
dongxuelian2:codex/fix-opcua-username-token-2791
Open

dongxuelian2 wants to merge 1 commit into
apache:developfrom
dongxuelian2:codex/fix-opcua-username-token-2791

Conversation

@dongxuelian2

Copy link
Copy Markdown

What does this change, and why?

When a username token's effective security policy is None, PLC4J sends the encrypted-secret preparation block (length, UTF-8 password and server nonce) as the password. Servers expecting the password itself reject ActivateSession with BadUserAccessDenied.

Send only the UTF-8 password for None and construct the length/password/nonce block only when encrypting. Encode encryptionAlgorithm as a null UA String (Int32 -1). OPC UA Part 4, UserNameIdentityToken permits null or empty for an unencrypted password; null also interoperates with asyncua 1.1.5, which does not decode the empty-string case as plaintext. Empty is not prohibited by the specification.

The selected UserTokenPolicy continues to govern token encryption independently of the SecureChannel policy. The existing allow-insecure-credentials opt-in and endpoint selection remain unchanged. No security-policy fallback is added.

Fixes #2791.

How was it tested?

  • New protocol regression suite: before: 30 tests, 17 failures and 1 error; after: 30 passed. Covers raw UTF-8 bytes, empty/omitted passwords, a 256-byte unencrypted password, null String wire encoding, nonce/length placement, policy inheritance and overrides, credential refusal and encryption failure propagation. Independently decrypts 25 real RSA tokens across all five supported encrypting policies, including empty, UTF-8 and 64-byte passwords.
  • mvnw.cmd -Pwith-java -pl plc4j/drivers/opcua -am test: 4,309 passed, 21 skipped, no failures/errors. OPC UA: 470 passed, 18 skipped, including existing certificate, encryption and endpoint-selection tests. The skipped OPC UA tests require Docker/Milo (17) or a real keystore (1). Other skips are existing platform/disabled tests.
  • Real PLC4J client against a loopback-only asyncua 1.1.5 fixture: original and password-only versions both reject all six None-token credential cases; the final fix satisfies all 16 authentication/read expectations. ASCII, UTF-8, empty and long plaintext passwords, encrypted tokens on a None channel, an encrypted channel, anonymous access, wrong credentials and the insecure-credentials guard were checked. Successful reads return Int32 42. Encrypted authentication works without the insecure-credentials opt-in.
  • Normal Apache RAT checks and git diff --check passed. Environment: Windows 11, JDK 21.0.9, pinned Maven 4.0.0-rc-5.

Integration limits: the fixture advertises its certificate in None-channel CreateSession responses because current develop otherwise fails earlier when the certificate is absent. Authentication/decryption code is unmodified. An existing encrypted CloseSecureChannel (CLO) decoding error occurs on both original and fixed versions after successful reads; these results verify authentication and reads, not clean encrypted shutdown. Docker/Milo, physical PLCs and the full multi-platform CI matrix were not run.

The final branch includes a subsequent Go/documentation-only develop update; the tested PLC4J, protocols and code-generation trees and Maven configuration are identical.

AI disclosure: OpenAI Codex generated the patch, regression tests and this description, and ran the reported automated checks. Human review is pending. No third-party implementation was copied into this contribution; the new test retains the ASF license header.

Checklist

Send the raw UTF-8 password when the effective user token policy is None,
and encode the absent encryption algorithm as null for interoperability.
Build the length/password/nonce block only for encrypted tokens.

Add wire-format and policy-selection regression tests, including real RSA
encryption/decryption, UTF-8 and empty passwords, and credential refusal.

Fixes apache#2791.

Generated-by: OpenAI Codex
Apache-ai: Code and tests generated by OpenAI Codex; human review pending.
@sruehl
sruehl requested a review from splatch October 19, 2026 16:10
@github-actions

Copy link
Copy Markdown
Contributor

Hi @dongxuelian2,

Before we review a pull-request from a new contributor, we ask them to introduce themselves on our developer mailing list, dev@plc4x.apache.org. Our contribution guidelines explain why: PLC4X is maintained by a small group of people, and reviewing a change costs us far more time than producing it.

Please post a short introduction covering:

  • who you are and your background, for example the protocols, PLCs or machines you work with
  • what you want to achieve with this pull-request, and the use case behind it
  • whether you plan to keep contributing

To subscribe, send an empty mail to dev-subscribe@plc4x.apache.org (see Getting in contact). Once your introduction is on the list, link the thread from the archive here. A maintainer will then remove the needs-introduction label and continue with the review.

Pull-requests without an introduction may be closed. If such a pull-request contains a valid finding, we may apply the change ourselves.

This comment is posted automatically on pull-requests from first-time contributors.

@github-actions github-actions Bot added the needs-introduction Waiting for the author to introduce themselves on dev@plc4x.apache.org label Oct 19, 2026
@dongxuelian2

Copy link
Copy Markdown
Author

Thanks for the instructions!

I've subscribed to the PLC4X developer mailing list and sent my introduction, covering my background in automation, the motivation behind this OPC UA fix, and my use of AI-assisted development.

I'll add the public mailing-list archive link here once the message becomes available.

I'm happy to address any review feedback. Thanks for your time!

@QuanticPony QuanticPony removed the needs-introduction Waiting for the author to introduce themselves on dev@plc4x.apache.org label Oct 20, 2026
@dongxuelian2

dongxuelian2 commented Oct 21, 2026 •

Copy link
Copy Markdown
Author

Thanks for the instructions. My introduction is now publicly archived on the PLC4X developer mailing list:
https://www.mail-archive.com/dev@plc4x.apache.org/msg13463.html

I'm happy to address any review feedback. Thank you for your consideration.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: OPC UA UserNameIdentityToken sends length+password+nonce instead of the plain password when token security policy is None

2 participants