Luis Amell / IBMIoTF-2

Dependencies:   MQTT

Revision:
5:ea9f483e0294
Child:
18:ce12e2072cbb
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MQTTNetwork.h	Tue May 30 06:24:06 2017 +0000
@@ -0,0 +1,237 @@
+/*******************************************************************************
+ * Copyright (c) 2017 IBM Corp.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ *    http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ *   http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *    Lokesh K Haralakatta  Initial implementation to support mbed OS 5
+ *    Lokesh K Haralakatta  Added SSL/TLS Support
+ *******************************************************************************/
+#ifndef MQTTNetwork_H
+#define MQTTNetwork_H
+
+// Network related header files
+#include "NetworkInterface.h"
+#include "EthernetInterface.h"
+
+// mbedTLS related header files
+#include "mbedtls/platform.h"
+#include "mbedtls/ssl.h"
+#include "mbedtls/entropy.h"
+#include "mbedtls/ctr_drbg.h"
+#include "mbedtls/error.h"
+#include "mbedtls/debug.h"
+
+//Include certificates header
+#include "Certificates.h"
+
+namespace IoTF {
+
+     //Class to represent Network layer
+     class MQTTNetwork {
+         private:
+             //Pointer member for ethernet interface
+             NetworkInterface* network;
+
+             //Pointer member to represent socket
+             TCPSocket* socket;
+
+             //Variable to stored server port
+             int serverPort;
+
+             //Poniter mebers for mbedTLS structures
+             mbedtls_entropy_context* _entropy;
+             mbedtls_ctr_drbg_context* _ctr_drbg;
+             mbedtls_x509_crt* _cacert;
+             mbedtls_ssl_context* _ssl;
+             mbedtls_ssl_config* _ssl_conf;
+         public:
+             //Default constructor to initialize network, mbedTLS structures
+             MQTTNetwork(): serverPort(1883){
+                 //Instantiate new ethernet interface
+                 network = new EthernetInterface();
+                 //Connect to ethernet interface
+                 network->connect();
+                 //Create socket with created ethernet interface
+                 socket = new TCPSocket(network);
+
+                 //Instantiate mbedTLS structures
+                 _entropy = new mbedtls_entropy_context();
+                 _ctr_drbg = new mbedtls_ctr_drbg_context();
+                 _cacert = new mbedtls_x509_crt();
+                 _ssl = new mbedtls_ssl_context();
+                 _ssl_conf = new mbedtls_ssl_config();
+
+                 //Initialize mbedTLS structures
+                 mbedtls_entropy_init(_entropy);
+                 mbedtls_ctr_drbg_init(_ctr_drbg);
+                 mbedtls_x509_crt_init(_cacert);
+                 mbedtls_ssl_init(_ssl);
+                 mbedtls_ssl_config_init(_ssl_conf);
+             }
+
+             //Getter method to return underlying EthernetInterface
+             NetworkInterface* getEth()
+             {
+                 return network;
+             }
+
+             //Destructor to release the resources
+             ~MQTTNetwork() {
+                 //Release mbedTLS resources
+                 mbedtls_entropy_free(_entropy);
+                 mbedtls_ctr_drbg_free(_ctr_drbg);
+                 mbedtls_x509_crt_free(_cacert);
+                 mbedtls_ssl_free(_ssl);
+                 mbedtls_ssl_config_free(_ssl_conf);
+
+                 //Free the allocated memory for socket and network pointers
+                 delete socket;
+                 delete network;
+
+                 //Free the allocated memory for mbedTLS structures
+                 delete _entropy;
+                 delete _ctr_drbg;
+                 delete _cacert;
+                 delete _ssl;
+                 delete _ssl_conf;
+             }
+
+             //Connect method to establish TCP socket connection
+             //If port=1883, opens unsecured socket connection
+             //If port is other than 1883, opens secured socket connection
+             int connect(const char*host, int port){
+                int rc = -1;
+
+                serverPort = port;
+                if(port == 1883)
+                     //Establish unsecured socket connection
+                     rc = socket->connect(host, port);
+                else{
+                        //Establish secure socket connection using SSL/TLS
+                        //Perform mbedTLS initialization
+                        if((rc = initializeTLS(host)) == 0){
+                           if((rc = socket->connect(host, port))==0){
+                             printf("Socket connection to %s:%d successful...\r\n",host,port);
+                             //Perform SSL handshake
+                             if ((rc = mbedtls_ssl_handshake(_ssl)) < 0) {
+                                     if (rc != MBEDTLS_ERR_SSL_WANT_READ &&
+                                             rc != MBEDTLS_ERR_SSL_WANT_WRITE) {
+                                     printf("mbedtls_ssl_handshake failed - 0x%x\r\n", -rc);
+                                     }
+                                    goto exit;
+                             }
+                           }
+                        }
+                }
+
+                exit:
+                        return rc;
+             }
+
+             //Method to initialize mbedTLS structures
+             int initializeTLS(const char* hostName){
+                     int rc = 0;
+
+                     //Initialize entropy seeding
+                     if ((rc = mbedtls_ctr_drbg_seed(_ctr_drbg, mbedtls_entropy_func, _entropy,
+                                       (const unsigned char *) tlsClientName,
+                                       sizeof (tlsClientName))) != 0) {
+                         printf("mbedtls_crt_drbg_init failed - 0x%x\r\n", -rc);
+                         goto exit;
+                     }
+
+                     //Parse certificates into mbedTLS structure
+                     if ((rc = mbedtls_x509_crt_parse(_cacert, (const unsigned char *) serverCert,
+                                        sizeof(serverCert))) != 0) {
+                         printf("mbedtls_x509_crt_parse for serverCert failed - 0x%x\r\n", -rc);
+                         goto exit;
+                     }
+
+                     //Set ssl config details
+                     if ((rc = mbedtls_ssl_config_defaults(_ssl_conf,
+                                     MBEDTLS_SSL_IS_CLIENT,
+                                     MBEDTLS_SSL_TRANSPORT_STREAM,
+                                     MBEDTLS_SSL_PRESET_DEFAULT)) != 0) {
+                         printf("mbedtls_ssl_config_defaults failed - 0x%x\r\n", -rc);
+                         goto exit;
+                     }
+
+                     //Add parsed server certificate to ssl config
+                     mbedtls_ssl_conf_ca_chain(_ssl_conf, _cacert, NULL);
+
+                     mbedtls_ssl_conf_rng(_ssl_conf, mbedtls_ctr_drbg_random, _ctr_drbg);
+
+                     //Set Server Certificate authorization mode
+                     mbedtls_ssl_conf_authmode(_ssl_conf, MBEDTLS_SSL_VERIFY_NONE);
+
+                     //Perform mbedTLS ssl setup
+                     if ((rc = mbedtls_ssl_setup(_ssl, _ssl_conf)) != 0) {
+                         printf("mbedtls_ssl_setup failed - 0x%x\r\n", -rc);
+                         goto exit;
+                     }
+
+                     //Set hostname to establish SSL connection
+                     mbedtls_ssl_set_hostname(_ssl, hostName);
+
+                     //Set buffer I/O methods for SSL connection
+                     mbedtls_ssl_set_bio(_ssl, static_cast<void *>(socket),
+                                                tlsWrite, tlsRead, NULL );
+
+               exit:
+                     return rc;
+             }
+
+             //Method to read from SSL socket
+             static int tlsRead(void *ctx,unsigned char* buffer, size_t len) {
+                 TCPSocket *socket = static_cast<TCPSocket *>(ctx);
+                 int rc = socket->recv(buffer, len);
+                 return rc;
+             }
+
+             //Method to write to SSL socket
+             static int tlsWrite(void *ctx,const unsigned char* buffer, size_t len) {
+                 TCPSocket *socket = static_cast<TCPSocket *>(ctx);
+                 int rc = socket->send(buffer, len);
+                 return rc;
+             }
+
+             //Method to read MQTT Packets
+             int read(unsigned char* buffer, int len, int timeout) {
+                 int rc = 0;
+
+                 if(serverPort == 1883)
+                     rc = socket->recv(buffer,len);
+                 else
+                     rc = mbedtls_ssl_read(_ssl, (unsigned char *) buffer, len);
+
+                 return rc;
+             }
+
+             //Method to send MQTT Packets
+             int write(unsigned char* buffer, int len, int timeout) {
+                 int rc = 0;
+
+                 if(serverPort == 1883)
+                     rc = socket->send(buffer,len);
+                 else
+                     rc = mbedtls_ssl_write(_ssl, (const unsigned char *) buffer, len);
+
+                 return rc;
+             }
+
+             //Method to close socket connection
+             void disconnect(){
+                 socket->close();
+             }
+
+     };
+}
+#endif