0
votes

I'm using mosquitto as broker and Paho in client.when connect with tcp,all seems to be okay,and then I want to use TLS,here comes the problem. I first generated ca.key,ca.crt,then I use it to generated server.crt,server.key,client.crt,client.key;then I tried to us code in https://github.com/Lunatictwo/mqtt-ssl-java ,here's my code:

public static void main(String[] args) {
    // TODO Auto-generated method stub
    String address = "ssl://192.168.100.46:8883";
    String topic = "topic0";
    String caFilePath = "SSL/ca.crt";
    String clientCrtFilePath = "SSL/client.crt";
    String clientKeyFilePath = "SSL/client.key";
    String keyPassword = "1234567890";
    MemoryPersistence persistence = new MemoryPersistence();
    try {
        MqttConnectOptions options = new MqttConnectOptions();
        options.setCleanSession(false);
        options.setSocketFactory(SslUtil.getSocketFactory(caFilePath,clientCrtFilePath,clientKeyFilePath,keyPassword));

        MqttClient client;          
        client = new MqttClient(address,"java-client",persistence);
        client.connect(options);
        client.subscribe(topic);
        client.setCallback(new MyCallback());

        MqttMessage message = new MqttMessage();
        message.setPayload("MosquittoClient连接成功".getBytes());
        client.publish(topic,message);

        client.disconnect();
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

and when I run this demo,I got this in mosquitto:

New connection from 192.168.100.46 on port 8883.
1496799343: OpenSSL Error: error:140890B2:SSL routines:SSL3_GET_CLIENT_CERTIFICATE:no certificate returned
1496799343: Socket error on client (null), disconnecting.
1496799343: New connection from 192.168.100.46 on port 8883.
1496799343: OpenSSL Error: error:140890B2:SSL routines:SSL3_GET_CLIENT_CERTIFICATE:no certificate returned
1496799343: Socket error on client (null), disconnecting.

Here's the info in eclipse:

MqttException (0) - java.net.SocketException: Software caused connection abort: socket write error
at org.eclipse.paho.client.mqttv3.internal.ExceptionHelper.createMqttException(ExceptionHelper.java:38)
at org.eclipse.paho.client.mqttv3.internal.ClientComms$ConnectBG.run(ClientComms.java:690)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.net.SocketException: Software caused connection abort: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:109)
at java.net.SocketOutputStream.write(SocketOutputStream.java:153)
at sun.security.ssl.OutputRecord.writeBuffer(OutputRecord.java:431)
at sun.security.ssl.OutputRecord.write(OutputRecord.java:417)
at sun.security.ssl.SSLSocketImpl.writeRecordInternal(SSLSocketImpl.java:876)
at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:847)
at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:717)
at sun.security.ssl.Handshaker.sendChangeCipherSpec(Handshaker.java:1077)
at sun.security.ssl.ClientHandshaker.sendChangeCipherAndFinish(ClientHandshaker.java:1222)
at sun.security.ssl.ClientHandshaker.serverHelloDone(ClientHandshaker.java:1134)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:348)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:979)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:914)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1062)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387)
at org.eclipse.paho.client.mqttv3.internal.SSLNetworkModule.start(SSLNetworkModule.java:97)
at org.eclipse.paho.client.mqttv3.internal.ClientComms$ConnectBG.run(ClientComms.java:676)
... 1 more

it semms that my client didn't send its certificate to the broker,but shoudn't it send certificate automatically? thank you for your help.

2

2 Answers

0
votes

MQTT(Mosquitto) with SSL/TLS

My environment of developement is secure mosquitto server as a message queue broker with mqtt protocol and the eclipse paho client with openssl.

You can check my github

Here is what I've done with these stuffs.

Making a your own certificate file by script(OwnTracks) with openssl library.

Download a generate-CA.sh script using wget command as follows

mkdir CA
chmod 700 CA
cd CA

wget https://github.com/owntracks/tools/raw/master/TLS/generate-CA.sh .
./generate-CA.sh

You can check the all 6 files are created while executing the script which are :

ca.crt(certificates), ca.key(keys), ca.srl(serial number record),
localhost.crt, localhost.csr(request), localhost.key

sudo cp ca.crt /etc/mosquitto/ca
sudo cp localhost.crt localhost.key /etc/mosquitto/crt/

configuration of mosquitto.conf

vi /usr/local/mosquitto/mosquitto.conf 

Put the lines below at the end the file

listener 8883
protocol mqtt

cafile /etc/mosquitto/ca/ca.crt
certfile /etc/mosquitto/crt/localhost.crt
keyfile /etc/mosquitto/crt/localhost.key

require_certificate false   

#listener 1883  => all refuse except TLS secure connection.
#protocol mqtt

You can see now what you have with mosquitto_sub and mosquitto_pub executable in the bin folder

Start Broker

mosquitto -c mosquitto.conf 

start Subscribe
mosquitto_sub -h localhost -p 8883 --cafile /etc/mosquitto/ca_certficates/ca.crt -t hello

start Publish mosquitto_pub -h localhost -p 8883 --cafile /etc/mosquitto/ca_certficates/ca.crt -t hello -m "Test is Test"

Now, It's time to ready with java client.

Getting java client from the eclipse paho site

https://github.com/eclipse/paho.mqtt.java

I decided to make my own paho client with ant project. I also use the apache launcher project.

- apache-ant-1.9.4
- apache launcher

You should have some openssl java library like bouncycastle from the site https://www.bouncycastle.org/latest_releases.html

- bcpkix-jdk15on-157.jar
- bcprov-ext-jdk15on-157.jar
- bcprov-jdk15on-156.jar

After all this setup done, I've got a sslsocket factory named SslUtil.java.

https://gist.github.com/rohanag12/07ab7eb22556244e9698

This is latest version source. you can check old version of source from

https://gist.github.com/sharonbn/4104301

After that, I have to modify the Sample.java. There are more options than the original one.

The output when enter the help command.

Syntax:

Sample [-h] [-a publish|subscribe] [-t <topic>] [-m <message text>]
[-s 0|1|2] -b <hostname|IP address>] [-p <brokerport>] [-i <clientID>]

-h  Print this help text and quit
-q  Quiet mode (default is false)
-a  Perform the relevant action (default is publish)
-v  TLS/SSL enabled; true - (default is false)
-e  Path of ca certification file if v option turns on
-f  Path of client certification file if v option turns on
-y  Path of client key file if v option turns on
-t  Publish/subscribe to <topic> instead of the default
(publish: "Sample/Java/v3", subscribe: "Sample/#")
-m  Use <message text> instead of the default
("Message from MQTTv3 Java client")
-s  Use this QoS instead of the default (2)
-b  Use this name/IP address instead of the default (m2m.eclipse.org)
-p  Use this port instead of the default (1883)

-i  Use this client ID instead of SampleJavaV3_<action>
-c  Connect to the server with a clean session (default is false)


Security Options
-u Username
-z Password


TLS Options
-v  TLS/SSL enabled; true - (default is false)     -e  CA certification file with openssl generally
-f  Client certification file
-y  Client key file

You can then execute mqtt client using apache launcher. See the launcher.xml and several batch scripts. I assume your os must be windows, but it's not that difficult to find compatible command on your os out there.

Jvm arguments in my launcher.xml file as follows.

subscribe: -a subscribe -b 192.9.112.155 -p 8883 -e resources/ca/ca.crt -f resources/ca/wap1.crt -y resources/ca/wap1.key -v true -z secret publish: -a publish -b 192.9.112.155 -p 8883 -e resources/ca/ca.crt -f resources/ca/wap1.crt -y resources/ca/wap1.key -v true -z secret -m 'this is a message from me'

Finally, My sub/pub log here.

>SET JAVA_HOME=C:\DEV\COMP\Java\jdk1.8.0_111

>SET ANT_HOME=C:\DEV\Tools\apache-ant-1.9.4

>SET CLASSPATH=.

>java -cp . LauncherBootstrap -verbose -executablename mqtt_paho_simple_subscriber mqtt_paho_simple_subscriber_secure
>>>>>>>>>>>>>>Encrypted key - we will use provided password
tlsmode.. true ...connection to ssl://xxx.xxx.xxx.xxx:8883
Connected to ssl://xxx.xxx.xxx.xxx:8883 with client ID SampleJavaV3_subscribe
Subscribing to topic "Sample/#" qos 2
Press <Enter> to exit
Time:   2017-07-19 19:40:17.594  Topic: Sample/Java/v3  Message:        this is a message from me  QoS: 2


>java -cp . LauncherBootstrap -verbose -executablename mqtt_paho_simple_publisher mqtt_paho_simple_publisher_secure
>>>>>>>>>>>>>>Encrypted key - we will use provided password
tlsmode.. true ...connection to ssl://xxx.xxx.xxx.xxx:8883
Connecting to ssl://xxx.xxx.xxx.xxx:8883 with client ID SampleJavaV3_publish
Connected
Publishing at: 2017-07-19 19:40:17.562 to topic "Sample/Java/v3" qos 2
Disconnected

enter image description here enter image description here

note:

Check exec directory if all certificate files in the ca directory in the resources folder. I mean put the your cert files to the directory.

0
votes

you are using my code in Github. It seems that your cert files didn't effect. Make sure all your ca files in your directory "./SSL". You'd better generate ca files and try again.