This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

LAUNCHXL-CC3235SF: MQTT client application not able to connect to secure server

Part Number: LAUNCHXL-CC3235SF
Other Parts Discussed in Thread: CC3200, UNIFLASH, CC3235SF

I am trying to connect to secure Azure IoT Hub MQTT server using MQTT client application. It is able to connect to AP using given SSID and Security key. When it tries to connect to broker it gives connection error. Log messages are as below:

---------------------------

Device came up in Station mode
[WLAN EVENT] STA Connected to the AP: Baton300M , BSSID: ac:84:c6:91:44:24
[NETAPP EVENT] IP acquired by the device

Device has connected to Baton300M
Device IP Address is 192.168.1.101

.Connection to broker failed, Error code: -456
BRIDGE DISCONNECTION

On-board Client Disconnected

.
TO Complete - Closing all threads and resources
Unsubscribed from the topic /Broker/To/cc32xx
Unsubscribed from the topic /cc3200/ToggleLEDCmdL1
Unsubscribed from the topic /cc3200/ToggleLEDCmdL2
Unsubscribed from the topic /cc3200/ToggleLEDCmdL3

 Client Stop completed

--------------------------------------

Above messages keep repeating in loop.

I have enabled following #defines for secure connection:

/* enables secured client                                                    */
#define SECURE_CLIENT
/* enables client authentication by the server                               */
#define CLNT_USR_PWD
 
Also provided values for macros - SERVER_ADDRESS and SERVER_IP_ADDRESS
In addition following strings are populated:
char *ClientId = clientname;                             //length of client name is 14 chars
/* Client User Name and Password                                             */
const char *ClientUsername = username;          //length of user name is 68 chars (could this be an issue?)
const char *ClientPassword = passowrd;           //length of password is 148 chars (could this be an issue?)
 
I am not using certificate file for authentication. (could this be an issue?)
 
If I connect to non-secure MQTT server like "broker.hivemq.com" then I am able to connect successfully. Problem occurs only for secured connections. 
I have used MQTT,Fx tool on PC to connect to my secured MQTT server using same clientname, username and password and it got connected successfully. This means that there is no issue on server side for connectivity.
 
Can any one help me resolving this issue please?
  • error -456 means that there is a problem with the ROOT-CA certificate you provided (SL_ERROR_BSD_ESECBADCAFILE).

    It is either the format of the certificate is wrong or the path to certificate file is wrong.

  • Is this ROOT-CA certificate downloaded in serial flash using Uniflash? Can I use default root certificate?

    If yes, then how do i set it's pointer in code. In mqtt_client_app.c file I can see this line of code :

    char *Mqtt_Client_secure_files[CLIENT_NUM_SECURE_FILES] = {"ca-cert.pem"};

    and I have set following structure in same file:

    MQTTClient_ConnParams Mqtt_ClientCtx =
    {
    MQTTCLIENT_NETCONN_IP4 | MQTTCLIENT_NETCONN_SEC,
    SERVER_IP_ADDRESS,                                      //SERVER_ADDRESS,
    SECURED_PORT_NUMBER,                              // PORT_NUMBER
    SLNETSOCK_SEC_METHOD_TLSV1_2,                   //SLNETSOCK_SEC_METHOD_SSLv3_TLSV1_2,
    SLNETSOCK_SEC_CIPHER_FULL_LIST,
    CLIENT_NUM_SECURE_FILES,
    Mqtt_Client_secure_files
    };

  • what you shared is the Root CA catalog which only contains the digests of the certificates. In addition you will need to store the root CA itself as a user file (in Uniflash/ImageCreator). 

    The path to this root-ca user file should be added to Mqtt_Client_secure_files array.

    Please refer to the secure-file section in the programmer's guide and to the certificate handling guide.

  • I downloaded "BaltimoreCyberTrustRoot.crt" in flash memory of CC3235SF LAUNCH Pad using Uniflash tool in user files section.

    I updated MQTT client example application and provided name of this file as shown below in mqtt_client_app.c file:

    char *Mqtt_Client_secure_files[CLIENT_NUM_SECURE_FILES] = {"BaltimoreCyberTrustRoot.crt"};

    Now I am getting different error code:

    ----------------------------------------

    evice came up in Station mode
    [WLAN EVENT] STA Connected to the AP: Baton300M , BSSID: ac:84:c6:91:44:24
    [NETAPP EVENT] IP acquired by the device

    Device has connected to Baton300M
    Device IP Address is 192.168.1.107

    ...Connection to broker failed, Error code: -468
    BRIDGE DISCONNECTION

    On-board Client Disconnected

    .
    TO Complete - Closing all threads and resources
    Unsubscribed from the topic /Broker/To/cc32xx
    Unsubscribed from the topic /cc3200/ToggleLEDCmdL1
    Unsubscribed from the topic /cc3200/ToggleLEDCmdL2
    Unsubscribed from the topic /cc3200/ToggleLEDCmdL3

    Client Stop completed

    ---------------------------------------------

    Please guide me on this error code.

  • It means that the root ca is not included in the certificate catalog. I guess you are using the "playground" catalog and not the official one because the official contains "Baltimore CyberTrust Root". One option is to switch to that one (then you will need a valid root ca to install the mcu image).

    Other option are to ignore this error (connection will still be opened when -468 is returned) or to disable it with sl_SetSockOpt (SL_SO_SECURE_DISABLE_CERTIFICATE_STORE).

    Using the mqttclient API you can set the MQTTCLIENT_NETCONN_SKIP_CERTIFICATE_CATALOG_VERIFICATION.

  • I added option to kip certificate catalog verification as below:

    MQTTClient_ConnParams Mqtt_ClientCtx =
    {
    MQTTCLIENT_NETCONN_IP4 | MQTTCLIENT_NETCONN_SEC | MQTTCLIENT_NETCONN_SKIP_CERTIFICATE_CATALOG_VERIFICATION,
    SERVER_IP_ADDRESS,                                      //SERVER_ADDRESS,
    SECURED_PORT_NUMBER,                              // PORT_NUMBER
    SLNETSOCK_SEC_METHOD_TLSV1_2,                   //SLNETSOCK_SEC_METHOD_SSLv3_TLSV1_2,
    SLNETSOCK_SEC_CIPHER_FULL_LIST,
    CLIENT_NUM_SECURE_FILES,
    Mqtt_Client_secure_files
    };

    Is above change correct?

    After rebuild and execute, the error code changed to -461.

     

    In Uniflash, I noticed that I have not checked "Use default Trusted Root-Certificate Catalog" check box and hence it was using 'playground' catalog. Now I have checked this checkbox. But it gives error while flashing the image and root certificate catalog:

  • -461 means SL_ERROR_BSD_ESECDATEERROR (see simplelink/errors.h) that connection failed because the date of the certificate is not valid.

    This typically means that the you didn't updated the time on your device.

    You can use the SNTP module (see attachment for example) or hardcoded setting using sl_DeviceSet(SL_DEVICE_GENERAL,
    SL_DEVICE_GENERAL_DATE_TIME,...) - see below.

    /*
     * Copyright (c) 2017, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     */
    
    #include <time.h>
    #include <unistd.h>
    
    #include <ti/display/Display.h>
    #include <ti/net/sntp/sntp.h>
    
    #define TIME_BASEDIFF        ((((uint32_t)70 * 365 + 17) * 24 * 3600))
    #define TIME_NTP_TO_LOCAL(t) ((t) - TIME_BASEDIFF)
    
    #define NTP_SERVERS 1
    #define NTP_SERVER_PORT 123
    
    /*  Time to wait for reply from server (seconds) */
    #define NTP_REPLY_WAIT_TIME 5
    
    /* Must wait at least 15 sec to retry NTP server (RFC 4330) */
    #define NTP_POLL_TIME 15
    
    extern Display_Handle display;
    
    /*
     *  ======== startSNTP ========
     */
    void startSNTP(void)
    {
        uint64_t ntpTimeStamp;
        uint32_t currentTime;
        int32_t retval;
        time_t ts;
        SlNetSock_Timeval_t timeval;
        struct timespec tspec;
    
        /* Set timeout value for NTP server reply */
        timeval.tv_sec = NTP_REPLY_WAIT_TIME;
        timeval.tv_usec = 0;
    
        do {
            /* Get the time use the built in NTP server list: */
            retval = SNTP_getTime(NULL, 0, &timeval, &ntpTimeStamp);
            if (retval != 0) {
                Display_printf(display, 0, 0,
                    "startSNTP: couldn't get time (%d), will retry in %d secs ...",
                    retval, NTP_POLL_TIME);
                sleep(NTP_POLL_TIME);
                Display_printf(display, 0, 0, "startSNTP: retrying ...");
            }
            currentTime = ntpTimeStamp >> 32;
    
            currentTime = TIME_NTP_TO_LOCAL(currentTime);
        } while (retval < 0);
    
        tspec.tv_nsec = 0;
        tspec.tv_sec = currentTime;
        if (clock_settime(CLOCK_REALTIME, &tspec) != 0) {
            Display_printf(display, 0, 0,
                    "startSNTP: Failed to set current time\n");
            while(1);
        }
    
        ts = time(NULL);
        Display_printf(display, 0, 0,
                "startSNTP: Current time: %s\n", ctime(&ts));
    }
    

    SlDateTime_t dateTime= {0};
    dateTime.tm_day = (_u32)23; // Day of month (DD format) range 1-31
    dateTime.tm_mon = (_u32)6; // Month (MM format) in the range of 1-12
    dateTime.tm_year = (_u32)2014; // Year (YYYY format)
    dateTime.tm_hour = (_u32)17; // Hours in the range of 0-23
    dateTime.tm_min = (_u32)55; // Minutes in the range of 0-59
    dateTime.tm_sec = (_u32)22; // Seconds in the range of 0-59
    sl_DeviceSet(SL_DEVICE_GENERAL,
    SL_DEVICE_GENERAL_DATE_TIME,
    sizeof(SlDateTime_t),
    (_u8 *)(&dateTime));

    regarding the uniflash issue: If you move to official catalog - you can't use the playground certificates anymore - you will need to use a certificate that was signed by a valid root ca that is included in the catalog.

  • After setting the current date and time it is giving me error code as -111. As per errors.h, this is connection refusal from server's end. I checked username, password, server name, etc and everything seems to be ok. I found some documentation mentioning below reasons for connection refusal:

    Is there anyway, I can find what is replied by server for connection refusal?

  • You should check the server's log.

  • Thanks Kobi...I will comeback if I get anything on client side.