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ライブラリ

MQTTSocket.h

Committer:
wolfSSL
Date:
2015-07-26
Revision:
46:d8968fcc21b8
Parent:
45:6c023c2ab095

File content as of revision 46:d8968fcc21b8:

#if !defined(MQTTSOCKET_H)
#define MQTTSOCKET_H

#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,  const char *certName = NULL, int timeout=1000)
    {

        mysock.set_blocking(false, timeout);    // 1 second Timeout
        isTLS = certName == NULL ? false : true ;
        int ret = mysock.connect(hostname, port);
        if((ret == 0) && isTLS) {
            return tls_connect(&mysock, certName) ;
        } else return ret ;
    }
    
    int read(unsigned char* buffer, int len, int timeout)
    {
        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 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;
    bool  isTLS ;
    WOLFSSL_CTX* ctx;
    WOLFSSL*     ssl;
    
    int tls_connect(TCPSocketConnection *sock, const char *certName)
    {
        /* 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;
        }
        if(*certName == '\0'){
            wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, 0);
        } else {
            if (wolfSSL_CTX_load_verify_locations(ctx, certName,0) != SSL_SUCCESS)
                printf("can't load ca file\n");
        }
        
        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 ;
        }
    }
};



#endif