← Back to team overview

mosquitto-users team mailing list archive

SSL connection from Java client to mosquitto broker: "no certificate returned"

 

Hello,

We are researching a push notifications platform for Android (a failover for Google's C2DM)
I am using the Eclipse Paho Java client to connect to mosquitto broker (1.0.3).  The broker is installed on a Ubuntu 12.04 (AWS EC2 instance)
I successfully connected the client to the server using non encrypted TCP connection.
By the way, after tweaking kernel params, I was able to open 100K concurrent clients to one broker instance on a medium sized EC2 machine.  Good work, mosquitto!

Now I am trying to set up a secured connection using SSL.  I want to authenticate the client using a client certificate.
I followed the explanations in mosquito_tls page and generated the keys and self-signed certificates for server and client.
Configured the server to use SSL.

For the client part, I looked at the signature of mosquitto_tls_set and took note that it requires the CA certificate, client key and certificate files.
I figured that the CA certificate is used for the client to authenticate the server, while the client key and certificate are used for the server to authenticate the client.
Am I right?

So I here is what I did on the Java side:

1)      Use bouncy castle to load the three abovementioned files.

2)      Put the CA certificate in a keystore and used it to create a TrustManagerFactory.

3)      Put the client key and certificate in another keystore and used it to create a KeyManagerFactory.

4)      Created an SSLContext an initialized it with the two factories.

5)      Created an SSLSocketFactory from the SSLContext and passed it to the Paho's MqttConnectOptions

When I do the connect, I get the following error from mosquitto

OpenSSL Error: error:140890B2:SSL routines:SSL3_GET_CLIENT_CERTIFICATE:no certificate returned
Socket read error on client (null), disconnecting.

Here's the full code

static SSLSocketFactory getSocketFactory (final String caCrtFile, final String crtFile, final String keyFile, final String password) throws Exception
{
      Security.addProvider(new BouncyCastleProvider());

      PEMReader reader = new PEMReader(new InputStreamReader(new ByteArrayInputStream(Files.readAllBytes(Paths.get(caCrtFile)))));
      X509Certificate caCert = (X509Certificate)reader.readObject();
      reader.close();

      reader = new PEMReader(new InputStreamReader(new ByteArrayInputStream(Files.readAllBytes(Paths.get(crtFile)))));
      X509Certificate cert = (X509Certificate)reader.readObject();
      reader.close();

      reader = new PEMReader(
                  new InputStreamReader(new ByteArrayInputStream(Files.readAllBytes(Paths.get(keyFile)))),
                  new PasswordFinder() {
                        public char[] getPassword() {
                              return password.toCharArray();
                        }
                  }
      );
      KeyPair key = (KeyPair)reader.readObject();
      reader.close();

      KeyStore caKs = KeyStore.getInstance("JKS");
      caKs.load(null, null);
      caKs.setCertificateEntry("ca-certificate", caCert);
      TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX");
      tmf.init(caKs);

      KeyStore ks = KeyStore.getInstance("JKS");
      ks.load(null, null);
      ks.setCertificateEntry("certificate", cert);
      ks.setKeyEntry("private-key", key.getPrivate(), password.toCharArray(), new java.security.cert.Certificate[]{cert});
      //ks.setKeyEntry("public-key", key.getPublic(), password.toCharArray(), new java.security.cert.Certificate[]{cert});
      KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
      kmf.init(ks, password.toCharArray());

      SSLContext context = SSLContext.getInstance("SSLv3");
      context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);

      return context.getSocketFactory();
}

The mosquito.conf looks like this

# general options
pid_file /home/ubuntu/mosquitto.pid

# persistence
queue_qos0_messages false
persistence false

# logging
log_dest stdout
connection_messages true
log_timestamp false

# default listener
# disable default listener (open only SSL listener)
#port 1883
#max_connections -1

# SSL listener
listener 1883
cafile /home/ubuntu/etc/ca.crt
certfile /home/ubuntu/etc/server.crt
keyfile /home/ubuntu/etc/server.key
require_certificate true
use_identity_as_username true
max_connections -1

Follow ups