Uploaded image for project: 'Qpid'
  1. Qpid
  2. QPID-8587

[Broker-J] SNI hostname handling for java 11/17 compatibility

    XMLWordPrintableJSON

Details

    • Improvement
    • Status: Closed
    • Minor
    • Resolution: Fixed
    • qpid-java-broker-8.0.6
    • qpid-java-broker-9.0.0
    • Broker-J
    • None

    Description

      When building Broker-J under Java 17 there is an error thrown in unit test:

      INFO] Running org.apache.qpid.server.transport.SNITestINFO] Running org.apache.qpid.server.transport.SNITest[ERROR] Tests run: 6, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 8.963 s <<< FAILURE! - in org.apache.qpid.server.transport.SNITest[ERROR] testBypassInvalidSniHostname(org.apache.qpid.server.transport.SNITest)  Time elapsed: 1.547 s  <<< ERROR!javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated at org.apache.qpid.server.transport.SNITest.performTest(SNITest.java:219) at org.apache.qpid.server.transport.SNITest.testBypassInvalidSniHostname(SNITest.java:172)

      The issue here seems to be more strict SNI hostname validation in Java 17 comparing to Java 11. 

      Stacktrace:

      java.base/sun.security.ssl.ServerNameExtension$CHServerNamesSpec.<init>(ServerNameExtension.java:138)
      java.base/sun.security.ssl.ServerNameExtension$CHServerNameConsumer.consume(ServerNameExtension.java:299)
      java.base/sun.security.ssl.SSLExtension.consumeOnLoad(SSLExtension.java:609)
      java.base/sun.security.ssl.SSLExtensions.consumeOnLoad(SSLExtensions.java:201)
      java.base/sun.security.ssl.ClientHello$T13ClientHelloConsumer.consume(ClientHello.java:1176)
      java.base/sun.security.ssl.ClientHello$ClientHelloConsumer.onClientHello(ClientHello.java:840)
      java.base/sun.security.ssl.ClientHello$ClientHelloConsumer.consume(ClientHello.java:801)
      java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:396)
      java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:480)
      java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask$DelegatedAction.run(SSLEngineImpl.java:1277)
      java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask$DelegatedAction.run(SSLEngineImpl.java:1264)
      java.base/java.security.AccessController.doPrivileged(AccessController.java:712)
      java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask.run(SSLEngineImpl.java:1209)
      org.apache.qpid.server.transport.NonBlockingConnectionTLSDelegate.runSSLEngineTasks(NonBlockingConnectionTLSDelegate.java:365)
      org.apache.qpid.server.transport.NonBlockingConnectionTLSDelegate.processData(NonBlockingConnectionTLSDelegate.java:144)
      org.apache.qpid.server.transport.NonBlockingConnection.doRead(NonBlockingConnection.java:496)
      org.apache.qpid.server.transport.NonBlockingConnection.doWork(NonBlockingConnection.java:270)
      org.apache.qpid.server.transport.NetworkConnectionScheduler.processConnection(NetworkConnectionScheduler.java:134)
      org.apache.qpid.server.transport.SelectorThread$ConnectionProcessor.processConnection(SelectorThread.java:545)
      org.apache.qpid.server.transport.SelectorThread$SelectionTask.performSelect(SelectorThread.java:345)
      org.apache.qpid.server.transport.SelectorThread$SelectionTask.run(SelectorThread.java:95)
      org.apache.qpid.server.transport.SelectorThread.run(SelectorThread.java:503)
      java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
      java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
      org.apache.qpid.server.bytebuffer.QpidByteBufferFactory.lambda$createQpidByteBufferTrackingThreadFactory$0(QpidByteBufferFactory.java:464)
      java.base/java.lang.Thread.run(Thread.java:833)

      SSLUtil#createSNIHostName now throws an exception even when passing a byte array instead of a string argument. This behavior change probably couldn't be avoided. As in unit test is used hostname "_foo" with the invalid underscore character, it will fail. 

      In Broker-J there is a possibility to ignore invalid SNI hostname provided by client introduced by QPID-8535. This is achieved by setting AMQP port context variable "qpid.port.amqp.ignoreInvalidSni" to true (default value false). When doing so client could provide an invalid SNI hostname (see Qpid JMS client configuration) and still be able to establish connection to the broker. This flag seem to have no effect since java 17, because the exception is thrown by sslEngine when performing the handshake.

      I would suggest marking flag "qpid.port.amqp.ignoreInvalidSni" as deprecated as its value will make no difference in future java versions since 17 and delete it and associated logic in one of the future broker major releases. Failing unit test SNITest#testBypassInvalidSniHostname() can be fixed by adding assume condition checking the java version.

      Attachments

        Activity

          People

            Unassigned Unassigned
            daniel.kirilyuk Daniil Kirilyuk
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: