MQTT and MQTTS with wolfSSL TSL library

Dependencies:   FP MQTTPacket

Dependents:   YoPlegma

Fork of MQTT by MQTT

MQTT is light weight publish/subscribe based messaging protocol for M2M, IoT. This library was forked from MQTT https://developer.mbed.org/teams/mqtt for adding MQTTS security layer on the protocol. TLS(SSL) part of the library is by wolfSSL.https://developer.mbed.org/users/wolfSSL/code/wolfSSL/

"connect" method was extended for TLS. Rest of API's stay compatible with MQTT.

connect methode

 int connect(char* hostname, int port,  const char *certName = NULL, int timeout=1000)

The 3rd argument certName can be following values.

  • NULL: connecting with MQTT
  • pointer to certificate file: connecting with MQTTS. PEM or DER for server verification.
  • pointer to NULL string: connecting with MQTTS without server verification. This option is for prototyping only, not recommended in security perspective.

日本語:https://developer.mbed.org/users/wolfSSL/code/MQTTS/wiki/MQTTSライブラリ

Revision:
45:6c023c2ab095
Parent:
43:21da1f744243
Child:
46:d8968fcc21b8
--- a/MQTTSocket.h	Mon Oct 06 11:41:05 2014 +0000
+++ b/MQTTSocket.h	Sun Jul 26 06:10:10 2015 +0000
@@ -3,37 +3,93 @@
 
 #include "MQTTmbed.h"
 #include "TCPSocketConnection.h"
+#include "wolfssl/ssl.h"
+#include    <wolfssl/wolfcrypt/error-crypt.h>
+
+static int SocketReceive(WOLFSSL* ssl, char *buf, int sz, void *sock)
+{
+    return ((TCPSocketConnection *)sock)->receive(buf, sz) ;
+}
+
+static int SocketSend(WOLFSSL* ssl, char *buf, int sz, void *sock)
+{
+    return ((TCPSocketConnection *)sock)->send(buf, sz);
+}
 
 class MQTTSocket
 {
-public:    
-    int connect(char* hostname, int port, int timeout=1000)
+public:
+    int connect(char* hostname, int port,  bool tls = false, int timeout=1000)
     {
-        mysock.set_blocking(false, timeout);    // 1 second Timeout 
-        return mysock.connect(hostname, port);
+
+        mysock.set_blocking(false, timeout);    // 1 second Timeout
+        isTLS = tls ;
+        int ret = mysock.connect(hostname, port);
+        if((ret == 0) && isTLS) {
+            return tls_connect(&mysock) ;
+        } else return ret ;
     }
-
+    
     int read(unsigned char* buffer, int len, int timeout)
     {
-        mysock.set_blocking(false, timeout);  
-        return mysock.receive((char*)buffer, len);
+        mysock.set_blocking(false, timeout);
+        return isTLS ?
+               wolfSSL_read(ssl, (char*)buffer, len) :
+               mysock.receive((char *)buffer, len) ;
     }
     
     int write(unsigned char* buffer, int len, int timeout)
     {
-        mysock.set_blocking(false, timeout);  
-        return mysock.send((char*)buffer, len);
+        mysock.set_blocking(false, timeout);
+        return isTLS ?
+               wolfSSL_write(ssl, (char*)buffer, len) :
+               mysock.send((char *)buffer, len) ;
     }
     
     int disconnect()
     {
+        if(isTLS) {
+            wolfSSL_free(ssl);
+            wolfSSL_CTX_free(ctx);
+            wolfSSL_Cleanup();
+        }
         return mysock.close();
     }
     
 private:
 
-    TCPSocketConnection mysock; 
-    
+    TCPSocketConnection mysock;
+    bool  isTLS ;
+    WOLFSSL_CTX* ctx;
+    WOLFSSL*     ssl;
+
+    int tls_connect(TCPSocketConnection *sock)
+    {
+        /* create and initiLize WOLFSSL_CTX structure */
+        if ((ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method())) == NULL) {
+            printf("SSL_CTX_new error.\n");
+            return EXIT_FAILURE;
+        }
+
+        wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, 0);
+        wolfSSL_SetIORecv(ctx, SocketReceive) ;
+        wolfSSL_SetIOSend(ctx, SocketSend) ;
+
+        if ((ssl = wolfSSL_new(ctx)) == NULL) {
+            printf("wolfSSL_new error.\n");
+            return EXIT_FAILURE;
+        }
+
+        wolfSSL_SetIOReadCtx(ssl, (void *)sock) ;
+        wolfSSL_SetIOWriteCtx(ssl, (void *)sock) ;
+
+        if (wolfSSL_connect(ssl) != SSL_SUCCESS) {
+            printf("TLS Connect error, %s\n", wc_GetErrorString(wolfSSL_get_error(ssl, 0)));
+            return EXIT_FAILURE;
+        } else {
+            return 0 ;
+        }
+    }
 };