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.javaI 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
smime.p7s
Description: S/MIME Cryptographic Signature
