Hi Connor, all,

thanks for your reply. However, I am trying to use the Netty protocol + enforcing mutual authentication under TLS v1.2. I am almost there... but I am stuck with an error that is difficult to debug and maybe, guys, you have some more insights.

Following this example:

 * 
http://svn.apache.org/repos/asf/avro/trunk/lang/java/ipc/src/test/java/org/apache/avro/ipc/TestNettyServerWithSSL.java

I am trying to build a small toolkit that will make secure communication between the requestor and the responder easy to deploy. For doing that, I have some working code that initializes a keystore and uses that for the source of trust, here's part of the code:

     // Instantiates a new responder
    Responder responder = new SpecificResponder(m_protoClass, m_protoHandler);

    // Gets a new Channel Factory
    ChannelFactory channelFactory = new 
NioServerSocketChannelFactory(Executors.newCachedThreadPool(), 
Executors.newCachedThreadPool());

    // Gets the responder
    //
    // NOTE:
    //
    // The m_trustManager is a helper class that extends 
NioClientSocketChannelFactory and
    // implements X509TrustManager, ChannelPipelineFactory, ChannelFactory

    m_server = new NettyServer(responder, new InetSocketAddress(m_host, m_port),
        channelFactory, (ChannelPipelineFactory) m_trustManager, null);

Internally the TrustManager implements the "*public ChannelPipeline getPipeline()*" method as follows:

    // We need to get the pipeline
    ChannelPipeline pipeline = Channels.pipeline();
                
    // Set up key manager factory to use our key store
    String algor = Security.getProperty("ssl.KeyManagerFactory.algorithm");
    if (algor == null) algor = "SunX509";
                
    KeyManagerFactory kmf = KeyManagerFactory.getInstance(algor);
    kmf.init(m_keyStore, null);
// Now let's instantiate a new SSLContext and initialize it with the
    // initialized KeyManagers
    SSLContext serverContext = SSLContext.getInstance("TLSv1.2");
    serverContext.init(kmf.getKeyManagers(), null, null);
// Let's create an SSLContext from which we will derive the SSLEngine
    SSLEngine sslEngine = serverContext.createSSLEngine();

    // DEBUGGING code that prints out the supported and enabled Ciphersuites
    System.out.println("TrustManager::SERVER Mode::Supported Ciphersuites:");
    String[] sCipher = sslEngine.getSupportedCipherSuites();
    for (int i = 0; i < sCipher.length; i++)
    {
       System.out.println("- " + sCipher[i]);
    }
    String[] eCipher = sslEngine.getEnabledCipherSuites();
    System.out.println("TrustManager::SERVER Mode::Enabled Ciphersuites:: ");
    for (int i = 0; i < eCipher.length; i++)
    {
      System.out.println("- " + eCipher[i]);
    }
                
    // Set Client / Server Mode. This is needed by the application to send
    // the right messages
    sslEngine.setUseClientMode(false);
                
    // Adds a new SslHandler that uses the instantiated SSLEngine to the 
pipeline
    pipeline.addLast("ssl", new SslHandler(sslEngine));
                
    // Return the pipeline
    return pipeline;

everything seems to be working fine, until the client tries to connect to the server - at that point, the server replies that there are no common ciphersuites with the client and exists. I also tried to connect with OpenSSL, but I get the same type of error from the server.

There is definitely something I am forgetting in the initialization of the server, probably, but I can't find what. Here's the trace:

607 [pool-5-thread-1] INFO org.apache.avro.ipc.NettyServer - [id: 0x21c61075, 
/127.0.0.1:47913 => /127.0.0.1:65000] OPEN
608 [pool-6-thread-1] INFO org.apache.avro.ipc.NettyServer - [id: 0x21c61075, 
/127.0.0.1:47913 => /127.0.0.1:65000] BOUND: /127.0.0.1:65000
608 [pool-6-thread-1] INFO org.apache.avro.ipc.NettyServer - [id: 0x21c61075, 
/127.0.0.1:47913 => /127.0.0.1:65000] CONNECTED: /127.0.0.1:47913
631 [pool-6-thread-1] WARN org.apache.avro.ipc.NettyServer - Unexpected 
exception from downstream.
*javax.net.ssl.SSLHandshakeException: no cipher suites in common*
        at sun.security.ssl.Handshaker.checkThrown(Handshaker.java:1362)
        at 
sun.security.ssl.SSLEngineImpl.checkTaskThrown(SSLEngineImpl.java:513)
        at sun.security.ssl.SSLEngineImpl.readNetRecord(SSLEngineImpl.java:793)
        at sun.security.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:761)
        at javax.net.ssl.SSLEngine.unwrap(SSLEngine.java:624)
        at org.jboss.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:938)
        at org.jboss.netty.handler.ssl.SslHandler.decode(SslHandler.java:656)
        at 
org.jboss.netty.handler.codec.frame.FrameDecoder.callDecode(FrameDecoder.java:286)
        at 
org.jboss.netty.handler.codec.frame.FrameDecoder.messageReceived(FrameDecoder.java:208)
        at 
org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:268)
        at 
org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:255)
        at org.jboss.netty.channel.socket.nio.NioWorker.read(NioWorker.java:94)
        at 
org.jboss.netty.channel.socket.nio.AbstractNioWorker.processSelectedKeys(AbstractNioWorker.java:364)
        at 
org.jboss.netty.channel.socket.nio.AbstractNioWorker.run(AbstractNioWorker.java:238)
        at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:38)
        at 
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
        at 
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
        at java.lang.Thread.run(Thread.java:724)
*Caused by: javax.net.ssl.SSLHandshakeException: no cipher suites in common*
        at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
        at sun.security.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1630)
        at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:278)
        at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:266)
        at 
sun.security.ssl.ServerHandshaker.chooseCipherSuite(ServerHandshaker.java:894)
        at 
sun.security.ssl.ServerHandshaker.clientHello(ServerHandshaker.java:622)
        at 
sun.security.ssl.ServerHandshaker.processMessage(ServerHandshaker.java:167)
        at sun.security.ssl.Handshaker.processLoop(Handshaker.java:868)
        at sun.security.ssl.Handshaker$1.run(Handshaker.java:808)
        at sun.security.ssl.Handshaker$1.run(Handshaker.java:806)
        at java.security.AccessController.doPrivileged(Native Method)
        at sun.security.ssl.Handshaker$DelegatedTask.run(Handshaker.java:1299)
        at org.jboss.netty.handler.ssl.SslHandler$3.run(SslHandler.java:1067)
        at 
org.jboss.netty.handler.ssl.ImmediateExecutor.execute(ImmediateExecutor.java:31)
        at 
org.jboss.netty.handler.ssl.SslHandler.runDelegatedTasks(SslHandler.java:1064)
        at org.jboss.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:954)
        ... 12 more
Exception in thread "main" org.apache.avro.AvroRemoteException: 
javax.net.ssl.SSLException: Received fatal alert: handshake_failure
        at 
org.apache.avro.ipc.specific.SpecificRequestor.invoke(SpecificRequestor.java:104)
        at com.sun.proxy.$Proxy5.send(Unknown Source)
        at org.datafascia.tests.testIPC.main(testIPC.java:153)
*Caused by: javax.net.ssl.SSLException: Received fatal alert: handshake_failure*
        at sun.security.ssl.Alerts.getSSLException(Alerts.java:208)
        at sun.security.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1630)
        at sun.security.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1598)
        at sun.security.ssl.SSLEngineImpl.recvAlert(SSLEngineImpl.java:1767)
        at sun.security.ssl.SSLEngineImpl.readRecord(SSLEngineImpl.java:1063)
        at sun.security.ssl.SSLEngineImpl.readNetRecord(SSLEngineImpl.java:887)
        at sun.security.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:761)
        at javax.net.ssl.SSLEngine.unwrap(SSLEngine.java:624)
        at org.jboss.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:938)
        at org.jboss.netty.handler.ssl.SslHandler.decode(SslHandler.java:656)
        at 
org.jboss.netty.handler.codec.frame.FrameDecoder.callDecode(FrameDecoder.java:286)
        at 
org.jboss.netty.handler.codec.frame.FrameDecoder.messageReceived(FrameDecoder.java:208)
        at 
org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:268)
        at 
org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:255)
        at org.jboss.netty.channel.socket.nio.NioWorker.read(NioWorker.java:94)
        at 
org.jboss.netty.channel.socket.nio.AbstractNioWorker.processSelectedKeys(AbstractNioWorker.java:364)
        at 
org.jboss.netty.channel.socket.nio.AbstractNioWorker.run(AbstractNioWorker.java:238)
        at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:38)
        at 
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
        at 
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
        at java.lang.Thread.run(Thread.java:724)
635 [pool-6-thread-1] INFO org.apache.avro.ipc.NettyServer - [id: 0x21c61075, 
/127.0.0.1:47913 :> /127.0.0.1:65000] DISCONNECTED
636 [pool-6-thread-1] INFO org.apache.avro.ipc.NettyServer - [id: 0x21c61075, 
/127.0.0.1:47913 :> /127.0.0.1:65000] UNBOUND
636 [pool-6-thread-1] INFO org.apache.avro.ipc.NettyServer - [id: 0x21c61075, 
/127.0.0.1:47913 :> /127.0.0.1:65000] CLOSED
637 [pool-6-thread-1] INFO org.apache.avro.ipc.NettyServer - Connection to 
/127.0.0.1:47913 disconnected.


Another question is: shall I use external libs (eg., BouncyCastle) to enable real TLS support ?

Cheers,
Max


On 09/26/2013 08:17 AM, Connor Doyle wrote:
Hi Max,

I did something similar recently to handle RPC calls from Node.js to our Scala 
services.

We use a WebSocket connection over SSL/TLS.  This reduces the overhead 
associated with handling a bunch of HTTP headers for every request.  Each 
connection begins with the client-server handshake as described in the spec.

To allow responses to flow back to each client in the order they complete, the 
client writes a sequence number in the metadata for each request.  The server 
writes this same sequence number into the metadata for the corresponding 
response.  This requires both endpoints to keep a little more state around.

--
Connor


--
Best Regards,
Dr. Massimiliano Pala
Senior Security Research Scientist
DataFASCIA

Attachment: smime.p7s
Description: S/MIME Cryptographic Signature

Reply via email to