Hi,<div><br></div><div><div>I&#39;m trying to develop my first high performance HTTPS based application using Netty, starting with the SecureChat and HTTP server examples. I noticed that the examples use a dummy implementation of TrustManager and load a KeyStore from a short[]. I assume that this is simply to make it convenient to get a working example to run. E.g. remove the need for someone to create a trust/key store before running the example.</div>

<div><br></div><div>I&#39;d like my app to use the default TrustStore/KeyStore loading from file (using system properties for config), as well as the standard certificate trust checks but am having trouble making the necessary modification. I kind of assumed that I could just pass SSLContext.init() some nulls and it would make sensible default choices, but I&#39;m getting a &quot;no cipher suites in common&quot; exception. </div>

<div><br></div><div>Here&#39;s a snippit of the code I&#39;m using (a modification of HttpServerPipelineFactory from the examples):</div><div><br></div><div><br></div><div><div>        // Create a default pipeline implementation.</div>

<div>        ChannelPipeline pipeline = pipeline();</div><div><br></div><div>        // Create TrustManagerFactory for PKIX-compliant trust managers</div><div>        TrustManagerFactory factory = TrustManagerFactory.getInstance(&quot;PKIX&quot;);</div>

<div>        KeyStore ks = null;</div><div>        factory.init(ks);</div><div>        SSLContext sslContext = SSLContext.getInstance(&quot;TLS&quot;);</div><div>       </div><div>        sslContext.init(null, factory.getTrustManagers(), null);</div>

<div><br></div><div>        TrustManager[] managers = factory.getTrustManagers();</div><div>        for (TrustManager m : managers) {</div><div>        <span class="Apple-tab-span" style="white-space:pre">        </span>X509TrustManager mgr = (X509TrustManager)m; </div>

<div>        <span class="Apple-tab-span" style="white-space:pre">        </span>for (X509Certificate c : mgr.getAcceptedIssuers()) {</div><div>        <span class="Apple-tab-span" style="white-space:pre">                </span>System.out.println(&quot;DEBUG: Trusted Certificate: &quot; + c.getSubjectDN());</div>

<div>        <span class="Apple-tab-span" style="white-space:pre">        </span>}</div><div>        }</div><div>        </div><div>        SSLEngine engine = sslContext.createSSLEngine();</div><div>        for (String suite : engine.getEnabledCipherSuites()) {</div>

<div>        <span class="Apple-tab-span" style="white-space:pre">        </span>System.out.println(&quot;DEBUG: Enabled cipher: &quot; + suite);</div><div>        }</div><div>        engine.setUseClientMode(false);</div><div>        </div>

<div>        pipeline.addLast(&quot;ssl&quot;, new SslHandler(engine));</div></div><div><br></div><div><br></div><div>When running this, I do see my loaded CA certificate (TrustStore) printed. I&#39;m not sure how to easily enumerate the private keys that are loaded, but I assume they&#39;re loaded as well. The ciphers enabled include:</div>

<div><br></div><div><div>SSL_RSA_WITH_RC4_128_MD5</div><div>SSL_RSA_WITH_RC4_128_SHA</div><div>TLS_RSA_WITH_AES_128_CBC_SHA</div><div>TLS_DHE_RSA_WITH_AES_128_CBC_SHA</div><div>TLS_DHE_DSS_WITH_AES_128_CBC_SHA</div><div>
SSL_RSA_WITH_3DES_EDE_CBC_SHA</div>
<div>SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA</div><div>SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA</div><div>SSL_RSA_WITH_DES_CBC_SHA</div><div>SSL_DHE_RSA_WITH_DES_CBC_SHA</div><div>SSL_DHE_DSS_WITH_DES_CBC_SHA</div><div>SSL_RSA_EXPORT_WITH_RC4_40_MD5</div>

<div>SSL_RSA_EXPORT_WITH_DES40_CBC_SHA</div><div>SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA</div><div>SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA</div><div>TLS_EMPTY_RENEGOTIATION_INFO_SCSV</div></div><div><br></div><div>When I try to connect, I get the following exception:</div>

<div><br></div><div><div>javax.net.ssl.SSLHandshakeException: no cipher suites in common</div><div>        at com.sun.net.ssl.internal.ssl.Handshaker.checkThrown(Unknown Source)</div><div>        at com.sun.net.ssl.internal.ssl.SSLEngineImpl.checkTaskThrown(Unknown Source)</div>

<div>        at com.sun.net.ssl.internal.ssl.SSLEngineImpl.readNetRecord(Unknown Source)</div><div>        at com.sun.net.ssl.internal.ssl.SSLEngineImpl.unwrap(Unknown Source)</div><div>        at javax.net.ssl.SSLEngine.unwrap(Unknown Source)</div>

<div>        at org.jboss.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:868)</div><div>        at org.jboss.netty.handler.ssl.SslHandler.decode(SslHandler.java:605)</div><div>        at org.jboss.netty.handler.codec.frame.FrameDecoder.callDecode(FrameDecoder.java:282)</div>

<div>        at org.jboss.netty.handler.codec.frame.FrameDecoder.messageReceived(FrameDecoder.java:216)</div><div>        at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:274)</div><div>        at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:261)</div>

<div>        at org.jboss.netty.channel.socket.nio.NioWorker.read(NioWorker.java:350)</div><div>        at org.jboss.netty.channel.socket.nio.NioWorker.processSelectedKeys(NioWorker.java:281)</div><div>        at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:201)</div>

<div>        at org.jboss.netty.util.internal.IoWorkerRunnable.run(IoWorkerRunnable.java:46)</div><div>        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)</div><div>        at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)</div>

<div>        at java.lang.Thread.run(Unknown Source)</div><div>Caused by: javax.net.ssl.SSLHandshakeException: no cipher suites in common</div><div>        at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)</div>

<div>        at com.sun.net.ssl.internal.ssl.SSLEngineImpl.fatal(Unknown Source)</div><div>        at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)</div><div>        at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)</div>

<div>        at com.sun.net.ssl.internal.ssl.ServerHandshaker.chooseCipherSuite(Unknown Source)</div><div>        at com.sun.net.ssl.internal.ssl.ServerHandshaker.clientHello(Unknown Source)</div><div>        at com.sun.net.ssl.internal.ssl.ServerHandshaker.processMessage(Unknown Source)</div>

<div>        at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Unknown Source)</div><div>        at com.sun.net.ssl.internal.ssl.Handshaker$1.run(Unknown Source)</div><div>        at java.security.AccessController.doPrivileged(Native Method)</div>

<div>        at com.sun.net.ssl.internal.ssl.Handshaker$DelegatedTask.run(Unknown Source)</div><div>        at org.jboss.netty.handler.ssl.SslHandler$2.run(SslHandler.java:999)</div><div>        at org.jboss.netty.handler.ssl.ImmediateExecutor.execute(ImmediateExecutor.java:37)</div>

<div>        at org.jboss.netty.handler.ssl.SslHandler.runDelegatedTasks(SslHandler.java:996)</div><div>        at org.jboss.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:886)</div><div>        ... 12 more</div></div>

<div><br></div><div>I saw <a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6448723">http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6448723</a> and wonder if my issue may be related. Would SSLContext.init() be initializing with an X509KeyManager instead of an X509ExtendedKeyManager as the bug report suggests I would require? If so, is there a convenient way of getting around this issue while maintaining the default keystore loading behavior?</div>

</div><div><br></div><div>Ultimately, I do want to validate the client certificate when it connects, if that changes anything. </div><div><br></div><div>I very much appreciate the attention you&#39;ve given if you&#39;ve made it this far :) Thanks!</div>

<div><br></div><div>Mathew Johnston</div>