jurmous / etcd4j

Java / Netty client for etcd, the highly-available key value store for shared configuration and service discovery.
Apache License 2.0
267 stars 83 forks source link

Bug/ssl context need client mode #195

Open bobpaulin opened 3 years ago

bobpaulin commented 3 years ago

It looks like the SSLContext should set

sslEngine.setUseClientMode(true)

proir to passing the SSLEngine to Netty (Seems to be related to https://mail.openjdk.java.net/pipermail/security-dev/2018-July/017715.html) . I've attached a test that will fail without the change testSSLContextClientModeSetSslEtcd.

I was using the camel-etcd "etcd-keys" component in Camel 3.7.0 which passes a SSLContext from javax.security rather than an SslContext from Netty. I was getting the exception below on Java 8 and 11.

java.io.IOException: java.lang.IllegalStateException: Client/Server mode not yet set.
    at mousio.etcd4j.promises.EtcdResponsePromise.get(EtcdResponsePromise.java:72)
    at org.apache.camel.component.etcd.EtcdKeysProducer.processGet(EtcdKeysProducer.java:93)
    at org.apache.camel.component.etcd.EtcdKeysProducer.process(EtcdKeysProducer.java:56)
    at org.apache.camel.support.AsyncProcessorConverterHelper$ProcessorToAsyncProcessorBridge.process(AsyncProcessorConverterHelper.java:66)
    at org.apache.camel.processor.SendProcessor.process(SendProcessor.java:169)
    at org.apache.camel.processor.errorhandler.RedeliveryErrorHandler$SimpleTask.run(RedeliveryErrorHandler.java:395)
    at org.apache.camel.impl.engine.DefaultReactiveExecutor$Worker.schedule(DefaultReactiveExecutor.java:148)
    at org.apache.camel.impl.engine.DefaultReactiveExecutor.scheduleMain(DefaultReactiveExecutor.java:60)
    at org.apache.camel.processor.Pipeline.process(Pipeline.java:147)
    at org.apache.camel.impl.engine.CamelInternalProcessor.process(CamelInternalProcessor.java:312)
    at org.apache.camel.component.timer.TimerConsumer.sendTimerExchange(TimerConsumer.java:207)
    at org.apache.camel.component.timer.TimerConsumer$1.run(TimerConsumer.java:76)
    at java.util.TimerThread.mainLoop(Timer.java:555)
    at java.util.TimerThread.run(Timer.java:505)
Caused by: java.lang.IllegalStateException: Client/Server mode not yet set.
    at sun.security.ssl.SSLEngineImpl.kickstartHandshake(SSLEngineImpl.java:680)
    at sun.security.ssl.SSLEngineImpl.writeAppRecord(SSLEngineImpl.java:1230)
    at sun.security.ssl.SSLEngineImpl.wrap(SSLEngineImpl.java:1186)
    at javax.net.ssl.SSLEngine.wrap(SSLEngine.java:509)
    at io.netty.handler.ssl.SslHandler.wrap(SslHandler.java:1038)
    at io.netty.handler.ssl.SslHandler.wrap(SslHandler.java:824)
    at io.netty.handler.ssl.SslHandler.wrapAndFlush(SslHandler.java:792)
    at io.netty.handler.ssl.SslHandler.flush(SslHandler.java:773)
    at io.netty.channel.AbstractChannelHandlerContext.invokeFlush0(AbstractChannelHandlerContext.java:748)
    at io.netty.channel.AbstractChannelHandlerContext.invokeFlush(AbstractChannelHandlerContext.java:740)
    at io.netty.channel.AbstractChannelHandlerContext.flush(AbstractChannelHandlerContext.java:726)
    at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.flush(CombinedChannelDuplexHandler.java:531)
    at io.netty.channel.ChannelOutboundHandlerAdapter.flush(ChannelOutboundHandlerAdapter.java:125)
    at io.netty.channel.CombinedChannelDuplexHandler.flush(CombinedChannelDuplexHandler.java:356)
    at io.netty.channel.AbstractChannelHandlerContext.invokeFlush0(AbstractChannelHandlerContext.java:748)
    at io.netty.channel.AbstractChannelHandlerContext.invokeFlush(AbstractChannelHandlerContext.java:740)
    at io.netty.channel.AbstractChannelHandlerContext.flush(AbstractChannelHandlerContext.java:726)
    at io.netty.handler.stream.ChunkedWriteHandler.doFlush(ChunkedWriteHandler.java:343)
    at io.netty.handler.stream.ChunkedWriteHandler.flush(ChunkedWriteHandler.java:133)
    at io.netty.channel.AbstractChannelHandlerContext.invokeFlush0(AbstractChannelHandlerContext.java:748)
    at io.netty.channel.AbstractChannelHandlerContext.invokeFlush(AbstractChannelHandlerContext.java:740)
    at io.netty.channel.AbstractChannelHandlerContext.flush(AbstractChannelHandlerContext.java:726)
    at io.netty.channel.DefaultChannelPipeline.flush(DefaultChannelPipeline.java:967)
    at io.netty.channel.AbstractChannel.flush(AbstractChannel.java:242)
    at mousio.etcd4j.transport.EtcdNettyClient.createAndSendHttpRequest(EtcdNettyClient.java:394)
    at mousio.etcd4j.transport.EtcdNettyClient.access$300(EtcdNettyClient.java:61)
    at mousio.etcd4j.transport.EtcdNettyClient$3.operationComplete(EtcdNettyClient.java:295)
    at mousio.etcd4j.transport.EtcdNettyClient$3.operationComplete(EtcdNettyClient.java:249)
    at io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:577)
    at io.netty.util.concurrent.DefaultPromise.notifyListeners0(DefaultPromise.java:570)
    at io.netty.util.concurrent.DefaultPromise.notifyListenersNow(DefaultPromise.java:549)
    at io.netty.util.concurrent.DefaultPromise.notifyListeners(DefaultPromise.java:490)
    at io.netty.util.concurrent.DefaultPromise.setValue0(DefaultPromise.java:615)
    at io.netty.util.concurrent.DefaultPromise.setSuccess0(DefaultPromise.java:604)
    at io.netty.util.concurrent.DefaultPromise.trySuccess(DefaultPromise.java:104)
    at io.netty.channel.DefaultChannelPromise.trySuccess(DefaultChannelPromise.java:84)
    at io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe.fulfillConnectPromise(AbstractNioChannel.java:300)
    at io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe.finishConnect(AbstractNioChannel.java:335)
    at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:702)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:650)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:576)
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493)
    at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
    at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
    at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
    at java.lang.Thread.run(Thread.java:748)

This PR should address the issue. Seemed like the most appropriate place to fix it. Please let me know if you have any