I have a RabbitMQ server (RabbitMQ version 3.6.0 with Erlang OTP 18.1) which supports only TLSv1.2 and the cipher {ecdhe_ecdsa,aes_256_cbc,sha384}. I am trying to connect to it from a Java client using AMQP. The source code looks as follows:
final SSLContext context = SSLContext.getInstance("TLSv1.2");
context.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null);
SSLContext.setDefault(context);
final String[] enabledCipherSuites = { "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384" };
final SSLParameters defaultParams = context.getDefaultSSLParameters();
defaultParams.setCipherSuites(enabledCipherSuites);
final SSLParameters supportedParams = context.getSupportedSSLParameters();
supportedParams.setCipherSuites(enabledCipherSuites);
ConnectionFactory factory = new ConnectionFactory();
factory.useSslProtocol(context);
factory.setHost(RABBITMQ_ADMIN_HOST);
factory.setPort(RABBITMQ_CLIENT_PORT_SSL);
factory.setUsername(RABBITMQ_ADMIN_USER);
factory.setPassword(RABBITMQ_ADMIN_PWD);
return factory.newConnection();
Here's a snippet from the RabbitMQ config file:
{ssl_options, [{cacertfile, "cacert.pem"},
{certfile, "cert.pem"},
{keyfile, "key.pem"},
{verify, verify_peer},
{versions, ['tlsv1.2']},
{ciphers, [{ecdhe_ecdsa,aes_256_cbc,sha384}]},
{fail_if_no_peer_cert, true}]}
The problem is, when the client tries to connect to server, the server disallows the connection with the following error:
=ERROR REPORT==== 4-Aug-2016::23:15:24 ===
SSL: hello: tls_handshake.erl:167:Fatal error: insufficient security
On the client side, we see a Java exception being thrown which looks like this:
Received fatal alert: insufficient_security
Thread-1 sun.security.ssl.Alerts.getSSLException(Alerts.java:192),
sun.security.ssl.Alerts.getSSLException(Alerts.java:154),
sun.security.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1991),
sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1098),
sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1344),
sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:721),
sun.security.ssl.AppOutputStream.write(AppOutputStream.java:122),
java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82),
java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140),
java.io.DataOutputStream.flush(DataOutputStream.java:123),
com.rabbitmq.client.impl.SocketFrameHandler.sendHeader(SocketFrameHandler.java:129),
com.rabbitmq.client.impl.SocketFrameHandler.sendHeader(SocketFrameHandler.java:134),
com.rabbitmq.client.impl.AMQConnection.start(AMQConnection.java:277),
com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:678),
com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:722)
The funny thing here is, despite setting the modified cipher suites in the default and supported ssl parameters, when we log the supported and default cipher suites, it shows everything else that should not be allowed as well !! I start the client with the following additional Java command line params:
-Dhttps.protocols=TLSv1.2
-Dhttps.cipherSuites=TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
-Ddeployment.security.TLSv1.2=true
-Ddeployment.security.TLSv1.1=false
-Ddeployment.security.SSLv3=false
Plus, while starting the client, I logged the enabled and default cipher suite. It shows a whole host of cipher suites instead of just the one that I specified.
Can someone help me figure out how I can fix this issue? Any pointer that would help me debug this would be very helpful.