Java 11 HTTP Server/Client SNI Support

793 views
Skip to first unread message

Vincent

unread,
Nov 13, 2018, 8:03:46 PM11/13/18
to vert.x
Hi,

I'm trying to have the Vertx HTTP server SNI work with the Vertx HTTP client (and WebClient) and and also NodeJS's HTTP client. It works perfectly in all the browsers I tested.

I was on 3.5.4 and then I upgraded to 3.6.0 but I still have the same problem.

I'm on Java 11.0.1.

The server is setup simply with :

HttpServerOptions()
.setPemKeyCertOptions(certOptions)
.setSsl(true)
.setSni(true)
.setUseAlpn(true)


And then I load certificates and keys for each "virtual hosts" with :

var certOptions = new PemKeyCertOptions().setKeyPaths(keyPaths).setCertPaths(certPaths);

Where keyPaths and certPaths are string paths pointing for the respective keys and certificates for the virtual hosts domains.

When debugging SSL with -Djavax.net.debug=ssl and making a request with Vertx's HTTP client, I get this (on the server side) :

javax.net.ssl|DEBUG|0F|vert.x-eventloop-thread-1|2018-11-14 24:36:32.245 UTC|Alert.java:232|Received alert message (
"Alert": {
 
"level"      : "warning",
 
"description": "close_notify"
}
)
javax
.net.ssl|WARNING|0F|vert.x-eventloop-thread-1|2018-11-14 24:36:32.247 UTC|SSLEngineOutputRecord.java:168|outbound has closed, ignore outbound application data
javax
.net.ssl|ALL|0F|vert.x-eventloop-thread-1|2018-11-14 24:43:23.256 UTC|X509Authentication.java:241|No X.509 cert selected for EC
javax
.net.ssl|ALL|0F|vert.x-eventloop-thread-1|2018-11-14 24:43:23.257 UTC|X509Authentication.java:241|No X.509 cert selected for EC
javax
.net.ssl|DEBUG|0F|vert.x-eventloop-thread-1|2018-11-14 24:43:23.482 UTC|Alert.java:232|Received alert message (
"Alert": {
 
"level"      : "fatal",
 
"description": "certificate_unknown"
}
)
javax
.net.ssl|ERROR|0F|vert.x-eventloop-thread-1|2018-11-14 24:43:23.487 UTC|TransportContext.java:313|Fatal (CERTIFICATE_UNKNOWN): Received fatal alert: certificate_unknown (
"throwable" : {
  javax
.net.ssl.SSLHandshakeException: Received fatal alert: certificate_unknown
  at java
.base/sun.security.ssl.Alert.createSSLException(Alert.java:128)
  at java
.base/sun.security.ssl.Alert.createSSLException(Alert.java:117)
  at java
.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:308)
  at java
.base/sun.security.ssl.Alert$AlertConsumer.consume(Alert.java:279)
  at java
.base/sun.security.ssl.TransportContext.dispatch(TransportContext.java:181)
  at java
.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:164)
  at java
.base/sun.security.ssl.SSLEngineImpl.decode(SSLEngineImpl.java:672)
  at java
.base/sun.security.ssl.SSLEngineImpl.readRecord(SSLEngineImpl.java:627)
  at java
.base/sun.security.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:443)
  at java
.base/sun.security.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:422)
  at java
.base/javax.net.ssl.SSLEngine.unwrap(SSLEngine.java:634)
  at io
.netty.handler.ssl.JdkSslEngine.unwrap(JdkSslEngine.java:90)
  at io
.netty.handler.ssl.Java9SslEngine.unwrap(Java9SslEngine.java:139)
  at io
.netty.handler.ssl.SslHandler$SslEngineType$3.unwrap(SslHandler.java:294)
  at io
.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1275)
  at io
.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1177)
  at io
.netty.handler.ssl.SslHandler.decode(SslHandler.java:1221)
  at io
.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:489)
  at io
.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:428)
  at io
.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:265)
  at io
.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
  at io
.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
  at io
.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
  at io
.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1434)
  at io
.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
  at io
.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
  at io
.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:965)
  at io
.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163)
  at io
.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:646)
  at io
.netty.channel.nio.NioEventLoop.processSelectedKeysPlain(NioEventLoop.java:546)
  at io
.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:500)
  at io
.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:460)
  at io
.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:884)
  at io
.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
  at java
.base/java.lang.Thread.run(Thread.java:834)}


)
javax
.net.ssl.SSLHandshakeException: Received fatal alert: certificate_unknown
 at java
.base/sun.security.ssl.Alert.createSSLException(Alert.java:128)
 at java
.base/sun.security.ssl.Alert.createSSLException(Alert.java:117)
 at java
.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:308)
 at java
.base/sun.security.ssl.Alert$AlertConsumer.consume(Alert.java:279)
 at java
.base/sun.security.ssl.TransportContext.dispatch(TransportContext.java:181)
 at java
.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:164)
 at java
.base/sun.security.ssl.SSLEngineImpl.decode(SSLEngineImpl.java:672)
 at java
.base/sun.security.ssl.SSLEngineImpl.readRecord(SSLEngineImpl.java:627)
 at java
.base/sun.security.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:443)
 at java
.base/sun.security.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:422)
 at java
.base/javax.net.ssl.SSLEngine.unwrap(SSLEngine.java:634)
 at io
.netty.handler.ssl.JdkSslEngine.unwrap(JdkSslEngine.java:90)
 at io
.netty.handler.ssl.Java9SslEngine.unwrap(Java9SslEngine.java:139)
 at io
.netty.handler.ssl.SslHandler$SslEngineType$3.unwrap(SslHandler.java:294)
 at io
.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1275)
 at io
.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1177)
 at io
.netty.handler.ssl.SslHandler.decode(SslHandler.java:1221)
 at io
.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:489)
 at io
.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:428)
 at io
.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:265)
 at io
.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
 at io
.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
 at io
.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
 at io
.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1434)
 at io
.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
 at io
.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
 at io
.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:965)
 at io
.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163)
 at io
.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:646)
 at io
.netty.channel.nio.NioEventLoop.processSelectedKeysPlain(NioEventLoop.java:546)
 at io
.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:500)
 at io
.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:460)
 at io
.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:884)
 at io
.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
 at java
.base/java.lang.Thread.run(Thread.java:834)


And this on the client side : 

javax.net.ssl.SSLHandshakeException: Failed to create SSL connection
 at io
.reactivex.internal.functions.Functions$OnErrorMissingConsumer.accept(Functions.java:704)
 at io
.reactivex.internal.functions.Functions$OnErrorMissingConsumer.accept(Functions.java:701)
 at io
.reactivex.internal.observers.ConsumerSingleObserver.onError(ConsumerSingleObserver.java:46)
 at io
.reactivex.internal.operators.single.SingleDoFinally$DoFinallyObserver.onError(SingleDoFinally.java:79)
 at io
.reactivex.internal.operators.single.SingleMap$MapSingleObserver.onError(SingleMap.java:69)
 at io
.vertx.reactivex.impl.AsyncResultSingle.lambda$subscribeActual$0(AsyncResultSingle.java:58)
 at io
.vertx.reactivex.ext.web.client.HttpRequest$9.handle(HttpRequest.java:514)
 at io
.vertx.reactivex.ext.web.client.HttpRequest$9.handle(HttpRequest.java:509)
 at io
.vertx.ext.web.client.impl.HttpContext.handleFailure(HttpContext.java:278)
 at io
.vertx.ext.web.client.impl.HttpContext.execute(HttpContext.java:272)
 at io
.vertx.ext.web.client.impl.HttpContext.next(HttpContext.java:247)
 at io
.vertx.ext.web.client.impl.HttpContext.fire(HttpContext.java:254)
 at io
.vertx.ext.web.client.impl.HttpContext.fail(HttpContext.java:234)
 at io
.vertx.ext.web.client.impl.HttpContext.lambda$handleSendRequest$8(HttpContext.java:390)
 at io
.vertx.core.impl.FutureImpl.tryFail(FutureImpl.java:170)
 at io
.vertx.core.http.impl.HttpClientRequestBase.handleException(HttpClientRequestBase.java:138)
 at io
.vertx.core.http.impl.HttpClientRequestImpl.lambda$null$8(HttpClientRequestImpl.java:503)
 at io
.vertx.core.impl.ContextImpl.executeTask(ContextImpl.java:320)
 at io
.vertx.core.impl.EventLoopContext.execute(EventLoopContext.java:43)
 at io
.vertx.core.impl.ContextImpl.executeFromIO(ContextImpl.java:188)
 at io
.vertx.core.impl.ContextImpl.executeFromIO(ContextImpl.java:180)
 at io
.vertx.core.http.impl.HttpClientRequestImpl.lambda$connect$9(HttpClientRequestImpl.java:502)
 at io
.vertx.core.http.impl.HttpClientImpl.lambda$getConnectionForRequest$5(HttpClientImpl.java:978)
 at io
.vertx.core.http.impl.ConnectionManager.lambda$getConnection$5(ConnectionManager.java:155)
 at io
.vertx.core.http.impl.pool.Pool.lambda$createConnection$4(Pool.java:317)
 at io
.vertx.core.impl.FutureImpl.tryFail(FutureImpl.java:170)
 at io
.vertx.core.http.impl.HttpChannelConnector.connectFailed(HttpChannelConnector.java:264)
 at io
.vertx.core.http.impl.HttpChannelConnector.lambda$doConnect$0(HttpChannelConnector.java:178)
 at io
.vertx.core.net.impl.ChannelProvider.lambda$connect$1(ChannelProvider.java:81)
 at io
.vertx.core.net.impl.ChannelProvider$1.userEventTriggered(ChannelProvider.java:113)
 at io
.netty.channel.AbstractChannelHandlerContext.invokeUserEventTriggered(AbstractChannelHandlerContext.java:329)
 at io
.netty.channel.AbstractChannelHandlerContext.invokeUserEventTriggered(AbstractChannelHandlerContext.java:315)
 at io
.netty.channel.AbstractChannelHandlerContext.fireUserEventTriggered(AbstractChannelHandlerContext.java:307)
 at io
.netty.handler.ssl.SslHandler.handleUnwrapThrowable(SslHandler.java:1202)
 at io
.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1183)
 at io
.netty.handler.ssl.SslHandler.decode(SslHandler.java:1221)
 at io
.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:489)
 at io
.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:428)
 at io
.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:265)
 at io
.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
 at io
.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
 at io
.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
 at io
.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1434)
 at io
.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
 at io
.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
 at io
.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:965)
 at io
.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163)
 at io
.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:646)
 at io
.netty.channel.nio.NioEventLoop.processSelectedKeysPlain(NioEventLoop.java:546)
 at io
.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:500)
 at io
.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:460)
 at io
.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:884)
 at io
.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
 at java
.base/java.lang.Thread.run(Thread.java:834)
Caused by: javax.net.ssl.SSLHandshakeException: Failed to create SSL connection
 at io
.vertx.core.net.impl.ChannelProvider$1.userEventTriggered(ChannelProvider.java:111)
 
... 24 more
Caused by: javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
 at java
.base/sun.security.ssl.Alert.createSSLException(Alert.java:128)
 at java
.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:321)
 at java
.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:264)
 at java
.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:259)
 at java
.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.checkServerCerts(CertificateMessage.java:642)
 at java
.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.onCertificate(CertificateMessage.java:461)
 at java
.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.consume(CertificateMessage.java:361)
 at java
.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:392)
 at java
.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:444)
 at java
.base/sun.security.ssl.SSLEngineImpl$DelegatedTask$DelegatedAction.run(SSLEngineImpl.java:1065)
 at java
.base/sun.security.ssl.SSLEngineImpl$DelegatedTask$DelegatedAction.run(SSLEngineImpl.java:1052)
 at java
.base/java.security.AccessController.doPrivileged(Native Method)
 at java
.base/sun.security.ssl.SSLEngineImpl$DelegatedTask.run(SSLEngineImpl.java:999)
 at io
.netty.handler.ssl.SslHandler.runDelegatedTasks(SslHandler.java:1435)
 at io
.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1343)
 at io
.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1177)
 
... 19 more
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
 at java
.base/sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:385)
 at java
.base/sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:290)
 at java
.base/sun.security.validator.Validator.validate(Validator.java:264)
 at java
.base/sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:321)
 at java
.base/sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:279)
 at java
.base/sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:141)
 at java
.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.checkServerCerts(CertificateMessage.java:620)
 
... 30 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
 at java
.base/sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141)
 at java
.base/sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126)
 at java
.base/java.security.cert.CertPathBuilder.build(CertPathBuilder.java:297)
 at java
.base/sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:380)
 
... 36 more
Exception in thread "vert.x-eventloop-thread-2" io.reactivex.exceptions.OnErrorNotImplementedException: The exception was not handled due to missing onError handler in the subscribe() method call. Further reading: https://github.com/ReactiveX/RxJava/wiki/Error-Handling | javax.net.ssl.SSLHandshakeException: Failed to create SSL connection
 at io
.reactivex.internal.functions.Functions$OnErrorMissingConsumer.accept(Functions.java:704)
 at io
.reactivex.internal.functions.Functions$OnErrorMissingConsumer.accept(Functions.java:701)
 at io
.reactivex.internal.observers.ConsumerSingleObserver.onError(ConsumerSingleObserver.java:46)
 at io
.reactivex.internal.operators.single.SingleDoFinally$DoFinallyObserver.onError(SingleDoFinally.java:79)
 at io
.reactivex.internal.operators.single.SingleMap$MapSingleObserver.onError(SingleMap.java:69)
 at io
.vertx.reactivex.impl.AsyncResultSingle.lambda$subscribeActual$0(AsyncResultSingle.java:58)
 at io
.vertx.reactivex.ext.web.client.HttpRequest$9.handle(HttpRequest.java:514)
 at io
.vertx.reactivex.ext.web.client.HttpRequest$9.handle(HttpRequest.java:509)
 at io
.vertx.ext.web.client.impl.HttpContext.handleFailure(HttpContext.java:278)
 at io
.vertx.ext.web.client.impl.HttpContext.execute(HttpContext.java:272)
 at io
.vertx.ext.web.client.impl.HttpContext.next(HttpContext.java:247)
 at io
.vertx.ext.web.client.impl.HttpContext.fire(HttpContext.java:254)
 at io
.vertx.ext.web.client.impl.HttpContext.fail(HttpContext.java:234)
 at io
.vertx.ext.web.client.impl.HttpContext.lambda$handleSendRequest$8(HttpContext.java:390)
 at io
.vertx.core.impl.FutureImpl.tryFail(FutureImpl.java:170)
 at io
.vertx.core.http.impl.HttpClientRequestBase.handleException(HttpClientRequestBase.java:138)
 at io
.vertx.core.http.impl.HttpClientRequestImpl.lambda$null$8(HttpClientRequestImpl.java:503)
 at io
.vertx.core.impl.ContextImpl.executeTask(ContextImpl.java:320)
 at io
.vertx.core.impl.EventLoopContext.execute(EventLoopContext.java:43)
 at io
.vertx.core.impl.ContextImpl.executeFromIO(ContextImpl.java:188)
 at io
.vertx.core.impl.ContextImpl.executeFromIO(ContextImpl.java:180)
 at io
.vertx.core.http.impl.HttpClientRequestImpl.lambda$connect$9(HttpClientRequestImpl.java:502)
 at io
.vertx.core.http.impl.HttpClientImpl.lambda$getConnectionForRequest$5(HttpClientImpl.java:978)
 at io
.vertx.core.http.impl.ConnectionManager.lambda$getConnection$5(ConnectionManager.java:155)
 at io
.vertx.core.http.impl.pool.Pool.lambda$createConnection$4(Pool.java:317)
 at io
.vertx.core.impl.FutureImpl.tryFail(FutureImpl.java:170)
 at io
.vertx.core.http.impl.HttpChannelConnector.connectFailed(HttpChannelConnector.java:264)
 at io
.vertx.core.http.impl.HttpChannelConnector.lambda$doConnect$0(HttpChannelConnector.java:178)
 at io
.vertx.core.net.impl.ChannelProvider.lambda$connect$1(ChannelProvider.java:81)
 at io
.vertx.core.net.impl.ChannelProvider$1.userEventTriggered(ChannelProvider.java:113)
 at io
.netty.channel.AbstractChannelHandlerContext.invokeUserEventTriggered(AbstractChannelHandlerContext.java:329)
 at io
.netty.channel.AbstractChannelHandlerContext.invokeUserEventTriggered(AbstractChannelHandlerContext.java:315)
 at io
.netty.channel.AbstractChannelHandlerContext.fireUserEventTriggered(AbstractChannelHandlerContext.java:307)
 at io
.netty.handler.ssl.SslHandler.handleUnwrapThrowable(SslHandler.java:1202)
 at io
.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1183)
 at io
.netty.handler.ssl.SslHandler.decode(SslHandler.java:1221)
 at io
.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:489)
 at io
.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:428)
 at io
.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:265)
 at io
.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
 at io
.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
 at io
.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
 at io
.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1434)
 at io
.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
 at io
.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
 at io
.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:965)
 at io
.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163)
 at io
.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:646)
 at io
.netty.channel.nio.NioEventLoop.processSelectedKeysPlain(NioEventLoop.java:546)
 at io
.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:500)
 at io
.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:460)
 at io
.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:884)
 at io
.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
 at java
.base/java.lang.Thread.run(Thread.java:834)
Caused by: javax.net.ssl.SSLHandshakeException: Failed to create SSL connection
 at io
.vertx.core.net.impl.ChannelProvider$1.userEventTriggered(ChannelProvider.java:111)
 
... 24 more
Caused by: javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
 at java
.base/sun.security.ssl.Alert.createSSLException(Alert.java:128)
 at java
.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:321)
 at java
.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:264)
 at java
.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:259)
 at java
.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.checkServerCerts(CertificateMessage.java:642)
 at java
.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.onCertificate(CertificateMessage.java:461)
 at java
.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.consume(CertificateMessage.java:361)
 at java
.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:392)
 at java
.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:444)
 at java
.base/sun.security.ssl.SSLEngineImpl$DelegatedTask$DelegatedAction.run(SSLEngineImpl.java:1065)
 at java
.base/sun.security.ssl.SSLEngineImpl$DelegatedTask$DelegatedAction.run(SSLEngineImpl.java:1052)
 at java
.base/java.security.AccessController.doPrivileged(Native Method)
 at java
.base/sun.security.ssl.SSLEngineImpl$DelegatedTask.run(SSLEngineImpl.java:999)
 at io
.netty.handler.ssl.SslHandler.runDelegatedTasks(SslHandler.java:1435)
 at io
.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1343)
 at io
.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1177)
 
... 19 more
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
 at java
.base/sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:385)
 at java
.base/sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:290)
 at java
.base/sun.security.validator.Validator.validate(Validator.java:264)
 at java
.base/sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:321)
 at java
.base/sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:279)
 at java
.base/sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:141)
 at java
.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.checkServerCerts(CertificateMessage.java:620)
 
... 30 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
 at java
.base/sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141)
 at java
.base/sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126)
 at java
.base/java.security.cert.CertPathBuilder.build(CertPathBuilder.java:297)
 at java
.base/sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:380)
 
... 36 more

When trying it with the NodeJS HTTP client, on the server side, I get this : 

javax.net.ssl|ALL|0F|vert.x-eventloop-thread-1|2018-11-14 24:59:15.764 UTC|SSLEngineImpl.java:743|Closing outbound of SSLEngine
javax
.net.ssl|ALL|0F|vert.x-eventloop-thread-1|2018-11-14 24:59:15.765 UTC|SSLEngineImpl.java:715|Closing inbound of SSLEngine
javax
.net.ssl|ERROR|0F|vert.x-eventloop-thread-1|2018-11-14 24:59:15.767 UTC|TransportContext.java:313|Fatal (INTERNAL_ERROR): closing inbound before receiving peer's close_notify (
"throwable" : {
  javax.net.ssl.SSLException: closing inbound before receiving peer'
s close_notify
  at java
.base/sun.security.ssl.Alert.createSSLException(Alert.java:129)
  at java
.base/sun.security.ssl.Alert.createSSLException(Alert.java:117)
  at java
.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:308)
  at java
.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:264)
  at java
.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:255)
  at java
.base/sun.security.ssl.SSLEngineImpl.closeInbound(SSLEngineImpl.java:724)
  at io
.netty.handler.ssl.JdkSslEngine.closeInbound(JdkSslEngine.java:55)
  at io
.netty.handler.ssl.SslHandler.setHandshakeFailure(SslHandler.java:1536)
  at io
.netty.handler.ssl.SslHandler.channelInactive(SslHandler.java:1023)
  at io
.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:245)
  at io
.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:231)
  at io
.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:224)
  at io
.netty.channel.DefaultChannelPipeline$HeadContext.channelInactive(DefaultChannelPipeline.java:1429)
  at io
.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:245)
  at io
.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:231)
  at io
.netty.channel.DefaultChannelPipeline.fireChannelInactive(DefaultChannelPipeline.java:947)
  at io
.netty.channel.AbstractChannel$AbstractUnsafe$8.run(AbstractChannel.java:822)
  at io
.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:163)
  at io
.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:404)
  at io
.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:464)
  at io
.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:884)
  at io
.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
  at java
.base/java.lang.Thread.run(Thread.java:834)}

And in NodeJS logs, I get : 

Error: unable to verify the first certificate
    at
TLSSocket.<anonymous> (_tls_wrap.js:1105:38)
    at emitNone
(events.js:106:13)
    at
TLSSocket.emit (events.js:208:7)
    at
TLSSocket._finishInit (_tls_wrap.js:639:8)
    at
TLSWrap.ssl.onhandshakedone (_tls_wrap.js:469:38)

The certificates are from Let's Encrypt and everything works fine with Safari, Chrome, Firefox and curl.

I have no idea what is going on. I have tried setting the SNI hostname/servername, to force SNI, etc. And nothing works.

I would love it if someone here could point me in the right direction.

Regards,

Vincent

Vincent

unread,
Nov 14, 2018, 12:26:18 PM11/14/18
to vert.x
I guess I was certain that both NodeJS (as of version 8) and Java (as of version 10) supported Let's Encrypt's CA. But I guess I was wrong since importing the CA pem file on the client side fixes the problem.

Vincent

unread,
Nov 14, 2018, 3:14:42 PM11/14/18
to vert.x
For those who might need it, what it actually was, is that I included the certificate you need to include in addCertPath is what Let's Encrypt calls the « fullchain » PEM file (not the « cert » file like I was before). Now, everything works with the CAs bundled with NodeJS and the Java 11 JVM.
Reply all
Reply to author
Forward
0 new messages