oscerd opened a new pull request, #27820: URL: https://github.com/apache/camel/pull/27820
## Description [CAMEL-25649](https://issues.apache.org/jira/browse/CAMEL-25649): `camel-netty`'s `hostnameVerification` option cannot verify anything. When it is enabled the TLS handshake fails for **every** certificate, matching or not: ``` javax.net.ssl.SSLHandshakeException: (certificate_unknown) Hostname or IP address is undefined. caused by java.security.cert.CertificateException: Hostname or IP address is undefined. ``` `DefaultClientInitializerFactory` created the engine with the no-arg `sslContext.createSSLEngine()` and then asked for host name verification. The JDK matches against `SSLSession.getPeerHost()`, which is only populated when the engine is created **with** the peer — with the no-arg form it stays `null`, and `HostnameChecker.match` opens with ```java if (expectedName == null) { throw new CertificateException("Hostname or IP address is undefined."); } ``` so the check never runs and the handshake is aborted instead. The option has been in this state since CAMEL-16315 (3.7.4 / 3.9.0). `camel-netty-http` is not affected: CAMEL-14070 gave its client engine `createSSLEngine(uri.getHost(), uri.getPort())` for SNI in 2019, so when CAMEL-20812 copied the verification block in, it landed on an engine that already carried the peer. The original in `camel-netty` never did — which is also why CAMEL-20812's reporter described the `camel-netty` implementation as the working one. ## Change Create the client engine with the configured host and port when `hostnameVerification` is enabled, as `camel-netty-http` does. The peer is attached **only** when the option is on. Attaching it also makes the JDK send the host as an SNI server name, and the default path should not change what goes on the wire. For routes that did set the option there is no regression to cause, because today they cannot connect at all. The consumer gets the same treatment when `clientMode=true`, where it really is a TCP client. ### Left out on purpose — the server side `DefaultServerInitializerFactory` applies the same block to a consumer acting as a server. There `endpointIdentificationAlgorithm=HTTPS` asks the JDK to match the **client's** certificate against a host name the server does not have, so whenever a client certificate is actually presented it fails the handshake the same way — and matching a client certificate against the client's address is not a meaningful control. I left that code as it is rather than remove a security-looking line unilaterally; the same block is in `camel-netty-http`'s `HttpServerInitializerFactory` and `HttpServerSharedInitializerFactory`. Happy to follow up whichever way reviewers prefer: drop the algorithm in server mode, or document the option as client-side only. CAMEL-25649 records the question. Also filed [CAMEL-25650](https://issues.apache.org/jira/browse/CAMEL-25650) (unassigned) for the structural reason this keeps recurring: nothing in `org.apache.camel.support.jsse` ever sets `endpointIdentificationAlgorithm`, so every component has to remember on its own and an operator cannot compensate from `sslContextParameters`. ## Tests New `NettySSLHostnameVerificationTest`, with a `keystore-localhost.jks` whose only subject alternative name is `DNS:localhost` (documented in `keystore-localhost.txt`, following the recipe the module already keeps in `keystore.txt`). The existing `keystore.jks` is `CN=CommonName` with no SANs, so it cannot test a match. - `localhost` with `hostnameVerification=true` connects and gets the reply. - `127.0.0.1` with `hostnameVerification=true` fails, and the assertion requires the message to name `127.0.0.1` — not just "it threw". Without that, the test would pass for the wrong reason: before the fix it also throws, with "Hostname or IP address is undefined". - `127.0.0.1` with the option off connects, so the option is what makes the difference. Revert-check — restoring the no-arg engine while keeping the tests: | test | result with the fix reverted | |---|---| | `connectsWhenTheCertificateMatchesTheHost` | **error**, `SSLHandshakeException: (certificate_unknown) Hostname or IP address is undefined.` | | `failsWhenTheCertificateDoesNotMatchTheHost` | **failure** on all 3 surefire runs: `got: Hostname or IP address is undefined.` | | `connectsToAHostTheCertificateDoesNotListWhenHostnameVerificationIsDisabled` | passes (the default path is untouched) | The behaviour was also confirmed outside Camel, with a client/server `SSLEngine` pair driven in memory on JDK 21.0.10: | client engine | `getPeerHost()` | result | |---|---|---| | `createSSLEngine()` | `null` | `CertificateException: Hostname or IP address is undefined.` | | `createSSLEngine("localhost", 443)` | `localhost` | handshake completes | | `createSSLEngine("other.example", 443)` | `other.example` | `CertificateException: No subject alternative DNS name matching other.example found.` | | Module | Tests | |---|---| | camel-netty | 133 (8 skipped) | `mvn -DskipTests install` in `components/camel-netty` regenerates no files beyond the edits in this PR. The catalog copy of the component page is a verbatim mirror and was re-synced (`diff` between the two is empty). I did not run the full reactor — the box is loaded — so I am relying on CI for that; nothing here touches `@UriParam` metadata. ## Docs - Component page: a new "Verifying the host name of the server" section — what the option checks, that an IP address needs its own subject alternative name, the two JDK failure messages, the SNI side effect, and that it does not apply to a consumer acting as a server. Mirrored to the catalog. - Upgrade guide 4.24: the option now verifies instead of failing. The default is unchanged. ## Backports Worth backporting to camel-4.22.x and camel-4.18.x after the merge — the option is equally broken there. The upgrade-guide entry stays on `main` only. 🤖 Generated with [Claude Code](https://claude.com/claude-code) -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
