3
votes

Where can I find the exact configuration setup for MQTT with SSL. The official docs just have it one line as " SSL is supported " but I could not find anything on how to configure it.

I have read a few forums, but I could not make out anything from it.

Some help on this.

P.S : Before you ask me what have I tried. I just made a route with mqtt as component in camel. I have a couple of certificates which I dont how to use it here.

1
Can you share your route code?Souciance Eqdam Rashti
Thanks for the comment . found the solution. Posting it as Answermadhairsilence

1 Answers

1
votes

To everyone who is looking for the instructions in the which does not even exists. Here is our you configure the MQTT component with SSL.

MQTT + SSL with Client , CA Certificate and a Key

Route

        MQTTEndpoint mqttEndpoint = null;
        MQTTComponent mqttComponent = new MQTTComponent();
        mqttComponent.setCamelContext( this.getContext()); //Set camel context

        mqttEndpoint = (MQTTEndpoint) mqttComponent.createEndpoint("mqtt://mqtt-queue"); //mqtt://<any-name>
        mqttEndpoint.getConfiguration().setHost( "ssl://<your-ssl-broker>" );

        SSLContext sc = SSLManager
                .getSocketFactory("<ca-certificate>.crt", "<trust-certificate>.crt", "<key>.key", <password>);
        mqttEndpoint.getConfiguration().setSubscribeTopicNames("<topic>");
        mqttEndpoint.getConfiguration().setSslContext( sc );

SSLContext

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openssl.PEMReader;
import org.bouncycastle.openssl.PasswordFinder;

import java.io.*;
import java.nio.file.*;
import java.security.*;
import java.security.cert.*;
import javax.net.ssl.*;


public class SSLManager
{
    public static SSLContext getSocketFactory (final String caCrtFile, final String crtFile, final String keyFile,
                                              final String password) throws Exception
    {

        Security.addProvider(new BouncyCastleProvider());

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

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

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

        // CA certificate is used to authenticate server
        KeyStore caKs = KeyStore.getInstance(KeyStore.getDefaultType());
        caKs.load(null, null);
        caKs.setCertificateEntry("ca-certificate", caCert);
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        tmf.init(caKs);

        // client key and certificates are sent to server so it can authenticate us
        KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
        ks.load(null, null);
        ks.setCertificateEntry("certificate", cert);
        ks.setKeyEntry("private-key", key.getPrivate(), password.toCharArray(), new java.security.cert.Certificate[]{cert});
        KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        kmf.init(ks, password.toCharArray());

        // create SSL socket factory
        SSLContext context = SSLContext.getInstance("TLSv1.2");
        //Create socket factory if required
        //context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);

        //return context.getSocketFactory();
        return context;        
    }
}

Maven Dependency

<dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcprov-jdk16</artifactId>
            <version>1.40</version>
        </dependency>