[ 
https://issues.apache.org/jira/browse/KNOX-3519?focusedWorklogId=1048341&page=com.atlassian.jira.plugin.system.issuetabpanels:worklog-tabpanel#worklog-1048341
 ]

ASF GitHub Bot logged work on KNOX-3519:
----------------------------------------

                Author: ASF GitHub Bot
            Created on: 20/Oct/26 02:52
            Start Date: 20/Oct/26 02:52
    Worklog Time Spent: 10m 
      Work Description: moresandeep opened a new pull request, #1459:
URL: https://github.com/apache/knox/pull/1459

   [KNOX-3519](https://issues.apache.org/jira/browse/KNOX-3519) - Set the JWKS 
host on the TLS socket so HTTPS endpoint identification works under BC-FIPS
   
   ## What changes were proposed in this pull request?
   
   Under the BouncyCastle FIPS JSSE provider, fetching a JWKS over HTTPS fails 
before any
   certificate is examined:
   
   ```
   java.security.cert.CertificateException: No hostname specified for HTTPS 
endpoint ID check
       at 
org.bouncycastle.jsse.provider.HostnameUtil.checkHostname(HostnameUtil.java:31)
       at 
org.bouncycastle.jsse.provider.ProvX509TrustManager.checkEndpointID(ProvX509TrustManager.java:333)
   ```
   
   JWT verification then fails and the request is rejected with 401, even when 
the JWKS
   endpoint's certificate is fully trusted and carries a matching SAN.
   
   
   **The change.** A new `SetHostSSLSocketFactory` decorator stamps the JWKS 
URL's host onto
   every socket it creates, via `setHost(String)` as declared by
   `org.bouncycastle.jsse.BCSSLSocket`. It is wired in at both JWKS retrieval 
paths:
   `DefaultTokenAuthorityService.buildJwkSource` (default truststore) and
   `IssuerTrustResourceRetriever` (per-issuer CA bundle).
   
   Notes on the implementation:
   
   - The BC type is reached reflectively, so Knox takes no compile dependency 
on the BouncyCastle
     TLS provider, it is present only in FIPS deployments. Lookup walks 
interfaces first,
     because BC's socket implementations are package-private and the method is 
only invocable
     through the public `BCSSLSocket` interface.
   - On sockets that do not expose `setHost` the decorator is a no-op. That is 
correct for the
     stock JSSE, which identifies HTTPS endpoints from the URL already, so 
non-FIPS deployments
     are unaffected.
   - Endpoint identification is **preserved, not bypassed**. The server 
certificate must still
     carry a SAN matching the JWKS host.
   - The retriever built for the default path reproduces Nimbus's own defaults 
exactly
     (connect/read 500 ms, 51200 byte limit, `disconnectAfterUse = true`), so 
timeout and size
     behaviour are unchanged.
   
   
   ## How was this patch tested?
   
   Patch was tested locally.
   
   




Issue Time Tracking
-------------------

            Worklog Id:     (was: 1048341)
    Remaining Estimate: 0h
            Time Spent: 10m

> Set the JWKS host on the TLS socket so HTTPS endpoint identification works 
> under BC-FIPS
> ----------------------------------------------------------------------------------------
>
>                 Key: KNOX-3519
>                 URL: https://issues.apache.org/jira/browse/KNOX-3519
>             Project: Apache Knox
>          Issue Type: Bug
>            Reporter: Sandeep More
>            Assignee: Sandeep More
>            Priority: Major
>          Time Spent: 10m
>  Remaining Estimate: 0h
>
> BC-FIPS HostnameUtil.checkHostname refuses IP literals for the HTTPS 
> algorithm, it matches DNS names only and never consults iPAddress SANs. So 
> the cert's IP Address:10.83.6.18 SAN is irrelevant, and no truststore change 
> can fix it. 
> THe result is when an ip address is used for SSL handshake throwing this error
> {code:java}
> 2026-10-19 23:15:18,262 42f8a538-720e-4467-ac21-e71c95f6f9c3 ERROR 
> token.state (DefaultTokenAuthorityService.java:verifyToken(371)) - Failed to 
> verify token using JWKS endpoint https://10.83.6.18:6443/openid/v1/jwks, 
> reason: com.nimbusds.jose.jwk.source.JWKSetRetrievalException: Couldn't 
> retrieve JWK set from URL: certificate_unknown(46)
> org.apache.knox.gateway.services.security.token.TokenServiceException: Cannot 
> verify token.
>         at 
> org.apache.knox.gateway.services.token.impl.DefaultTokenAuthorityService.verifyToken(DefaultTokenAuthorityService.java:331)
>         at 
> org.apache.knox.gateway.services.token.impl.DefaultTokenAuthorityService.verifyToken(DefaultTokenAuthorityService.java:365)
>         at 
> org.apache.knox.gateway.provider.federation.jwt.filter.AbstractJWTFilter.verifyTokenSignature(AbstractJWTFilter.java:966)
>         at 
> org.apache.knox.gateway.provider.federation.jwt.filter.AbstractJWTFilter.doFullTokenValidation(AbstractJWTFilter.java:765)
>         at 
> org.apache.knox.gateway.provider.federation.jwt.filter.AbstractJWTFilter.validateToken(AbstractJWTFilter.java:683)
>         at 
> org.apache.knox.gateway.provider.federation.jwt.filter.JWTFederationFilter.parseAndValidateJWT(JWTFederationFilter.java:733)
>         at 
> org.apache.knox.gateway.provider.federation.jwt.filter.JWTFederationFilter.parseAndValidateJWT(JWTFederationFilter.java:720)
>         at 
> org.apache.knox.gateway.provider.federation.jwt.filter.JWTFederationFilter.doFilter(JWTFederationFilter.java:346)
>         at 
> org.apache.knox.gateway.GatewayFilter$Holder.doFilter(GatewayFilter.java:391)
>         at 
> org.apache.knox.gateway.GatewayFilter$Chain.doFilter(GatewayFilter.java:305)
>         at 
> org.apache.knox.gateway.filter.XForwardedHeaderFilter.doFilter(XForwardedHeaderFilter.java:50)
>         at 
> org.apache.knox.gateway.filter.AbstractGatewayFilter.doFilter(AbstractGatewayFilter.java:59)
>         at 
> org.apache.knox.gateway.GatewayFilter$Holder.doFilter(GatewayFilter.java:391)
>         at 
> org.apache.knox.gateway.GatewayFilter$Chain.doFilter(GatewayFilter.java:305)
>         at 
> org.apache.knox.gateway.GatewayFilter.doFilter(GatewayFilter.java:191)
>         at 
> org.apache.knox.gateway.GatewayFilter.doFilter(GatewayFilter.java:102)
>         at 
> org.apache.knox.gateway.GatewayServlet.service(GatewayServlet.java:127)
>         at 
> org.eclipse.jetty.ee10.servlet.ServletHolder$NotAsync.service(ServletHolder.java:1387)
>         at 
> org.eclipse.jetty.ee10.servlet.ServletHolder.handle(ServletHolder.java:753)
>         at 
> org.eclipse.jetty.ee10.servlet.ServletHandler$ChainEnd.doFilter(ServletHandler.java:1624)
>         at 
> org.eclipse.jetty.ee10.websocket.servlet.WebSocketUpgradeFilter.doFilter(WebSocketUpgradeFilter.java:195)
>         at 
> org.eclipse.jetty.ee10.servlet.FilterHolder.doFilter(FilterHolder.java:205)
>         at 
> org.eclipse.jetty.ee10.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1596)
>         at 
> org.eclipse.jetty.ee10.servlet.ServletHandler$MappedServlet.handle(ServletHandler.java:1557)
>         at 
> org.eclipse.jetty.ee10.servlet.ServletChannel.dispatch(ServletChannel.java:828)
>         at 
> org.eclipse.jetty.ee10.servlet.ServletChannel.handle(ServletChannel.java:438)
>         at 
> org.eclipse.jetty.ee10.servlet.ServletHandler.handle(ServletHandler.java:470)
>         at 
> org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:575)
>         at 
> org.eclipse.jetty.ee10.servlet.SessionHandler.handle(SessionHandler.java:717)
>         at 
> org.eclipse.jetty.server.handler.ContextHandler.handle(ContextHandler.java:1102)
>         at 
> org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:181)
>         at org.eclipse.jetty.server.Handler$Wrapper.handle(Handler.java:740)
>         at 
> org.apache.knox.gateway.trace.TraceHandler.handle(TraceHandler.java:72)
>         at org.eclipse.jetty.server.Handler$Wrapper.handle(Handler.java:740)
>         at 
> org.apache.knox.gateway.filter.CorrelationHandler.handle(CorrelationHandler.java:50)
>         at org.eclipse.jetty.server.Handler$Wrapper.handle(Handler.java:740)
>         at 
> org.apache.knox.gateway.filter.PortMappingHelperHandler.handle(PortMappingHelperHandler.java:104)
>         at org.eclipse.jetty.server.Server.handle(Server.java:182)
>         at 
> org.eclipse.jetty.server.internal.HttpChannelState$HandlerInvoker.run(HttpChannelState.java:772)
>         at 
> org.eclipse.jetty.server.internal.HttpConnection.onFillable(HttpConnection.java:415)
>         at 
> org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:323)
>         at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105)
>         at 
> org.eclipse.jetty.io.SelectableChannelEndPoint$1.run(SelectableChannelEndPoint.java:53)
>         at 
> org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.runTask(AdaptiveExecutionStrategy.java:492)
>         at 
> org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.epcRunTask(AdaptiveExecutionStrategy.java:428)
>         at 
> org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.consumeTask(AdaptiveExecutionStrategy.java:401)
>         at 
> org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.tryProduce(AdaptiveExecutionStrategy.java:255)
>         at 
> org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.run(AdaptiveExecutionStrategy.java:204)
>         at 
> org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:311)
>         at 
> org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:981)
>         at 
> org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.doRunJob(QueuedThreadPool.java:1212)
>         at 
> org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1166)
>         at java.base/java.lang.Thread.run(Thread.java:840)
> Caused by: com.nimbusds.jose.jwk.source.JWKSetRetrievalException: Couldn't 
> retrieve JWK set from URL: certificate_unknown(46)
>         at 
> com.nimbusds.jose.jwk.source.URLBasedJWKSetSource.getJWKSet(URLBasedJWKSetSource.java:92)
>         at 
> com.nimbusds.jose.jwk.source.RetryingJWKSetSource.getJWKSet(RetryingJWKSetSource.java:99)
>         at 
> com.nimbusds.jose.jwk.source.OutageTolerantJWKSetSource.getJWKSet(OutageTolerantJWKSetSource.java:113)
>         at 
> com.nimbusds.jose.jwk.source.RateLimitedJWKSetSource.getJWKSet(RateLimitedJWKSetSource.java:107)
>         at 
> com.nimbusds.jose.jwk.source.CachingJWKSetSource.loadJWKSetNotThreadSafe(CachingJWKSetSource.java:330)
>         at 
> com.nimbusds.jose.jwk.source.RefreshAheadCachingJWKSetSource.loadJWKSetNotThreadSafe(RefreshAheadCachingJWKSetSource.java:347)
>         at 
> com.nimbusds.jose.jwk.source.CachingJWKSetSource.loadJWKSetBlocking(CachingJWKSetSource.java:240)
>         at 
> com.nimbusds.jose.jwk.source.RefreshAheadCachingJWKSetSource.getJWKSet(RefreshAheadCachingJWKSetSource.java:326)
>         at 
> com.nimbusds.jose.jwk.source.JWKSetBasedJWKSource.get(JWKSetBasedJWKSource.java:76)
>         at 
> com.nimbusds.jose.proc.JWSVerificationKeySelector.selectJWSKeys(JWSVerificationKeySelector.java:150)
>         at 
> com.nimbusds.jwt.proc.DefaultJWTProcessor.selectKeys(DefaultJWTProcessor.java:320)
>         at 
> com.nimbusds.jwt.proc.DefaultJWTProcessor.process(DefaultJWTProcessor.java:391)
>         at 
> com.nimbusds.jwt.proc.DefaultJWTProcessor.process(DefaultJWTProcessor.java:340)
>         at 
> com.nimbusds.jwt.proc.DefaultJWTProcessor.process(DefaultJWTProcessor.java:331)
>         at 
> org.apache.knox.gateway.services.token.impl.DefaultTokenAuthorityService.verifyToken(DefaultTokenAuthorityService.java:319)
>         ... 52 more
> Caused by: org.bouncycastle.tls.TlsFatalAlert: certificate_unknown(46)
>         at 
> org.bouncycastle.fips.tls/org.bouncycastle.jsse.provider.ProvSSLSocketDirect.checkServerTrusted(Unknown
>  Source)
>         at 
> org.bouncycastle.fips.tls/org.bouncycastle.jsse.provider.ProvTlsClient$1.notifyServerCertificate(Unknown
>  Source)
>         at 
> org.bouncycastle.fips.tls/org.bouncycastle.tls.TlsUtils.processServerCertificate(Unknown
>  Source)
>         at 
> org.bouncycastle.fips.tls/org.bouncycastle.tls.TlsClientProtocol.handleServerCertificate(Unknown
>  Source)
>         at 
> org.bouncycastle.fips.tls/org.bouncycastle.tls.TlsClientProtocol.receive13ServerCertificate(Unknown
>  Source)
>         at 
> org.bouncycastle.fips.tls/org.bouncycastle.tls.TlsClientProtocol.handle13HandshakeMessage(Unknown
>  Source)
>         at 
> org.bouncycastle.fips.tls/org.bouncycastle.tls.TlsClientProtocol.handleHandshakeMessage(Unknown
>  Source)
>         at 
> org.bouncycastle.fips.tls/org.bouncycastle.jsse.provider.ProvTlsClientProtocol.handleHandshakeMessage(Unknown
>  Source)
>         at 
> org.bouncycastle.fips.tls/org.bouncycastle.tls.TlsProtocol.processHandshakeQueue(Unknown
>  Source)
>         at 
> org.bouncycastle.fips.tls/org.bouncycastle.tls.TlsProtocol.processRecord(Unknown
>  Source)
>         at 
> org.bouncycastle.fips.tls/org.bouncycastle.tls.RecordStream.readRecord(Unknown
>  Source)
>         at 
> org.bouncycastle.fips.tls/org.bouncycastle.tls.TlsProtocol.safeReadRecord(Unknown
>  Source)
>         at 
> org.bouncycastle.fips.tls/org.bouncycastle.tls.TlsProtocol.blockForHandshake(Unknown
>  Source)
>         at 
> org.bouncycastle.fips.tls/org.bouncycastle.tls.TlsClientProtocol.connect(Unknown
>  Source)
>         at 
> org.bouncycastle.fips.tls/org.bouncycastle.jsse.provider.ProvSSLSocketDirect.startHandshake(Unknown
>  Source)
>         at 
> org.bouncycastle.fips.tls/org.bouncycastle.jsse.provider.ProvSSLSocketDirect.startHandshake(Unknown
>  Source)
>         at 
> java.base/sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:596)
>         at 
> java.base/sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:190)
>         at 
> java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1719)
>         at 
> java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1644)
>         at 
> java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:224)
>         at 
> com.nimbusds.jose.util.DefaultResourceRetriever.getInputStream(DefaultResourceRetriever.java:366)
>         at 
> com.nimbusds.jose.util.DefaultResourceRetriever.retrieveResource(DefaultResourceRetriever.java:269)
>         at 
> com.nimbusds.jose.jwk.source.URLBasedJWKSetSource.getJWKSet(URLBasedJWKSetSource.java:90)
>         ... 66 more
> Caused by: java.security.cert.CertificateException: No hostname specified for 
> HTTPS endpoint ID check
>         at 
> org.bouncycastle.fips.tls/org.bouncycastle.jsse.provider.HostnameUtil.checkHostname(Unknown
>  Source)
>         at 
> org.bouncycastle.fips.tls/org.bouncycastle.jsse.provider.ProvX509TrustManager.checkEndpointID(Unknown
>  Source)
>         at 
> org.bouncycastle.fips.tls/org.bouncycastle.jsse.provider.ProvX509TrustManager.checkEndpointID(Unknown
>  Source)
>         at 
> org.bouncycastle.fips.tls/org.bouncycastle.jsse.provider.ProvX509TrustManager.checkExtendedTrust(Unknown
>  Source)
>         at 
> org.bouncycastle.fips.tls/org.bouncycastle.jsse.provider.ProvX509TrustManager.checkTrusted(Unknown
>  Source)
>         at 
> org.bouncycastle.fips.tls/org.bouncycastle.jsse.provider.ProvX509TrustManager.checkServerTrusted(Unknown
>  Source)
>         ... 90 more {code}
>  



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to