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.

CC3100MOD: HTTPS CLIENT - HTTPCli_ECONNECTFAIL

Part Number: CC3100MOD
Other Parts Discussed in Thread: CC3100, UNIFLASH

Hello

I checked the Programmers Guide for the CC3100MOD but could not find any information about HTTPS Client connections.

I copied the HTTP Example from the recent SDK and modified it to use a TLS connection.

The current issue is that i always get the error code HTTPCli_ECONNECTFAIL during HTTPCli_connect().

When i use "curl" from my computer to deliver a POST, all works steamlessly.
Example: curl -X POST -H "Content-Type: application/octet-stream" --insecure --data-binary @REQUEST-FILE 192.168.1.20:1234/mymessage

To be clear here: I want to use the HTTPS servers self signed certificate for encryption, and i do NOT want, that the wifi module tries to validate that.

My suspicion is that this is happening, which, of course will fail.

Is there any more information i can extract, what is failing exaclty, because HTTPCli_ECONNECTFAIL is not really a lot of information.

int32_t http_server_connect(
char const * hostname, /* e.g. httpbin.org or 192.168.1.50 */
uint32_t const hostport) /* e.g. 80 */
{
int32_t ret = -1;
SlSockAddrIn_t addr;
uint32_t destinationIp;

assert( hostname );
assert( hostport );

log_internal("http_server_connect()\n");
log_internal(" HN: %s\n", hostname);
log_internal(" HP: %lu\n", hostport);

/* Resolve HOST NAME/IP */
ret = sl_NetAppDnsGetHostByName(
reinterpret_cast<signed char const*>(hostname),
rt_strlen(hostname),
&destinationIp,
SL_AF_INET);

if(ret < 0)
{
log_internal("Device couldn't get the IP for the host-name\n");
ASSERT_ON_ERROR_WITH_SL_STOP(ret);
}

/* Set up the input parameters for HTTP Connection */
addr.sin_family = SL_AF_INET;
addr.sin_port = sl_Htons(hostport);
addr.sin_addr.s_addr = sl_Htonl(destinationIp);

/* HTTPCli open call: handle, address params only */
HTTPCli_construct(&_sl_httpcli_cli);

// NO ISSUES UNTIL HERE
// HERE, I GET -102 ERROR CODE BACK

ret = HTTPCli_connect( // -102 > HTTPCli_ECONNECTFAIL
&_sl_httpcli_cli,
reinterpret_cast<SlSockAddr_t*>(&addr),
HTTPCli_TYPE_TLS,
nullptr);

if(ret < 0)
{
log_internal("Connection to server failed\n");
#warning "DEBUG"
while(1);
ASSERT_ON_ERROR_WITH_SL_STOP(ret);
}

log_internal("Successfully connected to the server\n");

return SUCCESS;
}

  • Hi,

    The CC3100 will not compare the root CA file used by the server against a trusted root CA store. Thus, you should have no problems using your self-signed certificate.

    The -102 error indicates that the HTTP client failed during the TLS connect stage. You most likely are either providing the root CA file to the CC3100 incorrectly, or have some other TLS misconfiguration. Have you taken a look at the wiki page for converting the HTTP demo to HTTPS?

    http://processors.wiki.ti.com/index.php/CC3200_HTTP_Client_Demo

    Also, have you tried connecting to your server using the ssl example? Using that example, you can test the TLS connect to your server without exercising the HTTP functionality. The error messages you from that example are more helpful that those from the HTTP library in debugging TLS connect issues.

    Regards,

    Michael

  • What i would like to accomplish is:

    1. Do not program ore use a SelfSigned Cert on the device at all, i would like to connect to the server and use TLS with the servers certificate. Is this not possible?

    2. Also, since during the first power on and server connection, i do not have the correct time and date, which might be an issue for the commiunication at all. Since it wont happen, i do not have access to date and time.

    If not i have a couple of questions:

    1. Is there someone I could call since it would likely answer all my questions in 15minutes.

    2. Why do i both need to have the cerificate on my MCU and programm it into the wifi module?

    3. Is there a way my MCU could transfer a CA over SPI to the wifi module? 

  • Hi,

    On the CC3xxx devices, when you are connecting with TLS, then you are required to provide the root CA used to sign the server's cert chain. This is a requirement that cannot be avoided.

    As for the date verification requirement, you could connect to an NTP server and get the network time at startup, before you connect to your server. The get_time example shows how you can do this in your code. Or, you could follow what the sslexample does and set a static time that you know is within the validity period of your server cert.

    As for having the cert on your MCU, what you actually need is the cert on the external flash of the CC3100. You could transfer the cert over SPI, using the sl_Fs* APIs to write a cert file to the external flash. However, it would be simpler to just provide the cert on the external flash along with the servicepack when you do the initial programming of the CC3100 using Uniflash or your production line programming method. This would remove the need to have the cert file on your MCU.

    Regards,
    Michael

  • Ok i tried the following:

    I first used Uniflash version 3 for the CC3100MOD and tried to flash a user file. Although i had no way of knowing if it was flashed, the console output suggested it did.

    I tried to read back the FS but this seems not to be supported in version 3.

    So i tried the sl_FsXXX API to read the file, which couldnt be found, i tried:

    - "/cert/c1.der"

    - "c1.der"

    When this failed, i manually flashed the file with the HOST MCU over the  sl_Fs API and validated if it has been written with the sl_Fs API.

    First success.

    Then, when connecting to the HTTPS Server, i got the following:

     SL_ESECBADCAFILE


    The communication partner is a local server running lubuntu. 

    >> What is failing here? What do i need to do with this error message? Please advise.

     

    CODE

    int32_t http_server_connect(

        char const     * hostname,      /* e.g. httpbin.org or 192.168.1.50 */

        uint32_t const   hostport)      /* e.g. 80                          */

    {

      int32_t        ret = -1;

      SlSockAddrIn_t addr;

      uint32_t       destinationIp;

      assert( hostname );

      assert( hostport );

      LOG("http_server_connect()\n");

      LOG("  HN: %s\n",  hostname);

      LOG("  HP: %lu\n", hostport);

      /* Resolve HOST NAME/IP */

      ret = sl_NetAppDnsGetHostByName(

          reinterpret_cast<signed char const*>(hostname),

          rt_strlen(hostname),

          &destinationIp,

          SL_AF_INET);

      if(ret < 0)

      {

        LOG("Device couldn't get the IP for the host-name\n");

        ASSERT_ON_ERROR_WITH_SL_STOP(ret);

      }

      /* Set up the input parameters for HTTP Connection */

      addr.sin_family      = SL_AF_INET;

      addr.sin_port        = sl_Htons(hostport);

      addr.sin_addr.s_addr = sl_Htonl(destinationIp);

      /* HTTPCli open call: handle, address params only */

      HTTPCli_construct(&_sl_httpcli_cli);

      unsigned long   MaxSize = 63 * 1024; //62.5K is max file size

      long            DeviceFileHandle = -1;

      long            RetVal;        //negative retval is an error

      unsigned long   Offset = 0;

      unsigned char   InputBuffer[100];

      RetVal = sl_FsDel((unsigned char *)"/cert/c1.der", 0); // SL_FS_FILE_HAS_NOT_BEEN_CLOSE_CORRECTLY -64

      // Create a file and write data. The file in this example is secured, without signature and with a fail safe commit

      RetVal = sl_FsOpen((unsigned char *)"/cert/c1.der",

                                       FS_MODE_OPEN_CREATE(

                                           MaxSize ,

                                           _FS_FILE_OPEN_FLAG_NO_SIGNATURE_TEST | _FS_FILE_OPEN_FLAG_COMMIT ),

                                       NULL,

                                       &DeviceFileHandle);

      Offset = 0;

      //Preferred in secure file that the Offset and the length will be aligned to 16 bytes.

      RetVal = sl_FsWrite( DeviceFileHandle, Offset, (unsigned char *)dummycert, sizeof(dummycert));

      RetVal = sl_FsClose(DeviceFileHandle, NULL, NULL , 0);

      // open the same file for read, using the Token we got from the creation procedure above

      RetVal = sl_FsOpen((unsigned char *)"/cert/c1.der", // -64

                                       FS_MODE_OPEN_READ,

                                       NULL, &DeviceFileHandle);

      Offset = 0;

      RetVal = sl_FsRead( DeviceFileHandle, Offset, (unsigned char *)InputBuffer, sizeof(InputBuffer));

      RetVal = sl_FsClose(DeviceFileHandle, NULL, NULL , 0); // -17

      SlDateTime_t dt;

      struct HTTPCli_SecureParams sparams;

      /* Set current Date to validate certificate */

      dt.sl_tm_day = 21;

      dt.sl_tm_mon = 6;

      dt.sl_tm_year = 2019;

      dt.sl_tm_hour = 12;

      dt.sl_tm_min = 0;

      dt.sl_tm_sec = 0;

      sl_DevSet(SL_DEVICE_GENERAL_CONFIGURATION,

                     SL_DEVICE_GENERAL_CONFIGURATION_DATE_TIME,

                                  sizeof(SlDateTime_t), (unsigned char *)(&dt));

    #define SL_SSL_CA_CERT "/cert/c1.der"

      /* Security parameters */

      sparams.method.secureMethod = SL_SO_SEC_METHOD_TLSV1_2;

      sparams.mask.secureMask  = SL_SEC_MASK_TLS_RSA_WITH_AES_256_CBC_SHA;

      strncpy(sparams.cafile, SL_SSL_CA_CERT, sizeof(SL_SSL_CA_CERT));

      sparams.privkey[0] = 0;

      sparams.cert[0] = 0;

      sparams.dhkey[0] = 0;

      HTTPCli_setSecureParams(&sparams);

      ret = HTTPCli_connect( //-102

          &_sl_httpcli_cli,

          reinterpret_cast<SlSockAddr_t*>(&addr),

          HTTPCli_TYPE_TLS,

          nullptr);

      if(ret < 0)

      {

        LOG("Connection to server failed\n");

        while(1)

          ;

        ASSERT_ON_ERROR_WITH_SL_STOP(ret);

      }

      LOG("Successfully connected to the server\n");

      return SUCCESS;

    }

  • Hi,

    SL_ESECBADCAFILE indicates that the certificate that you are programming onto the device is corrupt somehow. Typically this would be due to the cert not formatted as der, being written the filesystem incorrectly, or perhaps due to your original certificate being invalid somehow.

    I suggest you ensure that your certificate is formatted correctly.

    Also, you could try using your code and connecting to a public http server on the internet. I suggest you use the method outlined here to copy the root CA certs for a public server from your PC, to ensure that it is formatted correctly:

    https://e2e.ti.com/support/wireless-connectivity/wifi/f/968/p/673247/2478357#2478357

    That will allow you to check whether your code works. If it doesn't then getting it working with a well-known server would be a good debug step.

    Regards,

    Michael

  • Hi,

    I assume that you have resolved your issue since I have not heard back from you. If not, feel free to post a response to this thread, or open a new thread regarding this issue.

    Regards,
    Michael