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.

CCS/TM4C129ENCPDT: Using TLS for both- Simplelink and NDK

Part Number: TM4C129ENCPDT
Other Parts Discussed in Thread: CC3100, CC3120

Tool/software: Code Composer Studio

Hi All,

I am using ti rtos 2.16.1.14 and simple link SDK 1.2 with cc3100 and NDK also. I am using httpcli library with both, which itself gives the TLS support. Now I am using FTP with API given in socket.h, and I am able to use plain FTP very well with both- wifi and ethernet.

But now I have to use FTPS and for that, I need the TLS. The way tls has been implemented in httpcli library, I want TLS in the same way for FTPS also so that my application layer code doesn't get changed. 

Is there any way to do this? So far, I have seen that simplelink has provided separate TLS interface ( I am working currently on it) and ethernet has separate TLS (using Wolfssl, not working right now). If I need to implement separately, then that's not a good solution we need as there will be two different codes. I want something which has been done in httpcli library. Is there any way??

I tried to use httpcli library for ftp also but there I am getting protocol error (-370).

Thanks and Regards,

Akhilesh

  • Hi Akhilesh,

    Am I understanding correctly that the model used by the httpcli works for your application and is what you would like to use? If so, you should be able to follow what the httpcli is doing and start a secure socket using the Ssock_startTLS() API.

    Thanks,
    Gerardo

  • Hi Gerardo

    Your understanding is right. I know only API calls of httpcli library. I need TLS to attach on application layer which can work for both, simple link and ndk.

    Where can I find documents related to Ssock_startTLS api?

    I need to attach my plain socket to TLS while using socket api which are common in both, simple link and ndk.

    One more thing i want to elaborate here that i tried to use httpcli library for ftp. I am able to open control channel on port 21 and logged in using username and password. But after putting it into passive mode and trying to connect to the ftp server on the ip and port no sent by server, it fails to connect.

    Already there is 1 control channel on port 21 and i am trying to open data channel onto some other port no on the same server, it fails. Any reason why is it so? This was just if i can use httpcli for plain ftp client, may be i can use its TLS part also. Just experimental thing.

    Let me know what you think on both the things.

    Thanks,

    Akhilesh

  • Hi Akhilesh,

    Upon further inspection, it looks like the APIs used to start a secure TLS session by the HTTP Client by the two platforms are different. You can see what each platform does to establish the secure session by checking the source code, it can be found at:
    <CC3100_SDK_DIR>/netapps/http/client/
    <TIRTOS_DIR>/products/ns_1_11_00_10/packages/ti/net/http/
    So the code to establish the secure session for each platform will vary slightly, but once the session is established you can continue using socket APIs on both platforms. 

    What error are you receiving when you try to connect to the ftp server?

    Regards,
    Gerardo

  • Hi Gerado,

    I am able to use TLS for both, ndk and simplelink. I am using the component from TI RTOS. 

    Like this way-

    TLS_Params_init(&tlsParams);
    	    tlsParams.ca = ca_cert;// root ca cert array in .pem format
    	    tlsParams.calen = sizeof_ca_cert;
    	    g_tls = TLS_create(TLS_METHOD_CLIENT_TLSV1_2, &tlsParams, NULL);

    Same thing I am trying for ftps. I can use plain FTP using httpcli library. I can make socket connection on port 21, able to login in, able to open data connection also, everything on plain FTP. But when I try to use FTPS by including the TLS as mentioned above, I am getting the error -370 (SL_ESEC_PROTOCOL_VERSION) while connecting. I don't get this error in https but only in ftps. What can be the problem? If I can resolve this error, my work will be done. I have tried to change the TLS versions also, but same error.

    Thanks

    Akhilesh

  • Hi Akhilesh,

    Have you confirmed which version of the TLS protocol the server you're connecting to supports?

    Regards,
    Gerardo

  • Hi Gerardo,

    I checked. It supports tls1, 1.1 and 1.2.  But error exists as I tried with other versions too.

     Can you help?

    Thanks

    Akhilesh

  • Hi Akhilesh,

    Can you try your TLS connection using the SSL example from the SDK instead of the httpcli library? Does this also fail?

    Please be sure you have the latest servicepack flashed to the CC3100.

    Best regards,

    Sarah

  • Akhilesh,

    We are still looking at this, but what version of WolfSSL are you using? We have only validated against 3.8.

    Todd

  • Hi Sarah,

    I have tried that too. Same error I am getting. 

    Let me clarify a bit here. I have tried using the sl example provided by simplelink. In this, ftps, while connecting I am getting -370. 

    Previously I was getting -456 then I converted my .pem into .der and now I am getting -370.

    I also tried to use httpcli library. Same -370 I am getting there also.

    I am using Filezilla server for ftps and having the self-signed certificate generated using the filezilla server app. I don't have any firewall restrictions as I allowed all the packet inbound and outbound and also allowed filezilla through firewall. 

    This has taken a lot of time. I am attaching my code also for your reference(both httpcli and simplelink). It's not a production code just testing purposes so very less error handling I have implemented. If you want to try this, please use filezilla server and self-signed certificate.

    And Todd, I am not using wolfssl by myself. Just tried simplelink. But I would prefer to use httpcli.

    One more edit I want to add. This is explicit FTPs I am using on port 21. But when I use implicit ftps on port 990, I am getting -340. I dont want to use implicit ftps. was just trying.

    Thanks

    
    struct sockaddr_in g_addr1 = { 0 }, g_addr2={0};
    HTTPCli_Struct cli,cli1;
    int createFtpSocket(char *ipAddress, int portNr)
    {
        HTTPCli_Params params;
        HTTPCli_Field fields[1] = { { HTTPStd_FIELD_NAME_HOST, ipAddress },
    
        };
        char data[1025]; memset(data, 0, 1025);
    
        //Set request fields
        HTTPCli_construct(&cli);
        HTTPCli_setRequestFields(&cli, fields);
    
        TLS_Params tlsParams;
        TLS_Params_init(&tlsParams);
        tlsParams.ca = ca_cert1;
        tlsParams.calen = sizeof_ca_cert1;
        TLS_Handle g_tls = TLS_create(TLS_METHOD_CLIENT_TLSV1_2, &tlsParams, NULL);
        if (!g_tls)
        {
            logg("***ERROR*** - TLS_create failed", __FUNCTION__);
            return -1;
        }
        setTimeInSL(1577944922); memset(data, 0, 1025);
        HTTPCli_initSockAddr((struct sockaddr *) &g_addr1, ipAddress, 0);
        HTTPCli_Params_init(&params);
        params.tls = g_tls;
    
        int ret = HTTPCli_connect(&cli, (struct sockaddr *) &g_addr1,
                                  0,
                                  //   HTTPCli_TYPE_TLS,
                                  //  NULL
                                  &params );
    							  
    							  
    	/*********NOTE: If I select NULL, it conencts but tls wont work. If I select &params, I am getting -370 *********/
    
        ret = HTTPCli_getSocketError(&cli);
        HTTPCli_readRawResponseBody(&cli, data, sizeof(data) - 1);
        logStrInt("*response body is  %s and ret=%i", "", data, ret); logg("***************\n","");
    
    
    
        if (ret < 0)
        {
            logStrInt("***ERROR*** - connect failed %s ret=%i", __FUNCTION__, ipAddress, ret);
            return ret;
        }
        else
        {
            HTTPCli_readRawResponseBody(&cli, data, sizeof(data) - 1);
            logStrInt("*response body is  %s and ret=%i", "", data, ret); logg("***************\n","");
            memset(data, 0, 1025);
            return ret;
        }
    
    
    }
    
    
    
    bool pmoPosFtpProc(char* posCmd, char* result)
    {
    
        int sock = createFtpSocket(g_ftpHost, 21);
        if (sock < 0)
            return false;
    
        //Login
        char ftpCmd[200] = { 0 };
        memset(data, 0, 1025);
      //
        strcpy(ftpCmd, "AUTH "); strcat(ftpCmd, "TLS");  strcat(ftpCmd, "\r\n");
        int ret = HTTPCli_sendRequestBody(&cli, ftpCmd, sizeof(ftpCmd));
        if (ret < 0)
        {
            logStrInt("***ERROR*** - sendRequestBody reading file %s failed ret=%i","", ftpCmd, ret);
            return ret;
        }
        else
        {
            ret = HTTPCli_readRawResponseBody(&cli, data, sizeof(data) - 1);logg("***************\n","");
            logStrInt("*response body is  %s and ret=%i", "", data, ret);
            memset(data, 0, 1025); memset(ftpCmd, 0, 200);
        }
    
        strcpy(ftpCmd, "PBSZ 0"); //strcat(ftpCmd, 0);
        strcat(ftpCmd, "\r\n");
         ret = HTTPCli_sendRequestBody(&cli, ftpCmd, sizeof(ftpCmd));
        if (ret < 0)
        {
            logStrInt("***ERROR*** - sendRequestBody reading file %s failed ret=%i","", ftpCmd, ret);
            return ret;
        }
        else
        {
            ret = HTTPCli_readRawResponseBody(&cli, data, sizeof(data) - 1);logg("***************\n","");
            logStrInt("*response body is  %s and ret=%i", "", data, ret);
            memset(data, 0, 1025); memset(ftpCmd, 0, 200);
        }
    
    
        strcpy(ftpCmd, "PROT P");// strcat(ftpCmd, g_ftpHostUserId);
        strcat(ftpCmd, "\r\n");
         ret = HTTPCli_sendRequestBody(&cli, ftpCmd, sizeof(ftpCmd));
        if (ret < 0)
        {
            logStrInt("***ERROR*** - sendRequestBody reading file %s failed ret=%i","", ftpCmd, ret);
            return ret;
        }
        else
        {
            ret = HTTPCli_readRawResponseBody(&cli, data, sizeof(data) - 1);logg("***************\n","");
            logStrInt("*response body is  %s and ret=%i", "", data, ret);
            memset(data, 0, 1025); memset(ftpCmd, 0, 200);
        }
    
        strcpy(ftpCmd, "USER "); strcat(ftpCmd, g_ftpHostUserId);  strcat(ftpCmd, "\r\n");
         ret = HTTPCli_sendRequestBody(&cli, ftpCmd, sizeof(ftpCmd));
        if (ret < 0)
        {
            logStrInt("***ERROR*** - sendRequestBody reading file %s failed ret=%i","", ftpCmd, ret);
            return ret;
        }
        else
        {
            ret = HTTPCli_readRawResponseBody(&cli, data, sizeof(data) - 1);logg("***************\n","");
            logStrInt("*response body is  %s and ret=%i", "", data, ret);
            memset(data, 0, 1025); memset(ftpCmd, 0, 200);
        }
    
    
        strcpy(ftpCmd, "PASS "); strcat(ftpCmd, g_ftpHostPswd); strcat(ftpCmd, "\r\n");
        ret = HTTPCli_sendRequestBody(&cli, ftpCmd, sizeof(ftpCmd));
        if (ret < 0)
        {
            logStrInt("***ERROR*** - sendRequestBody reading file %s failed ret=%i", "", ftpCmd, ret);
            return ret;
        }
        else
        {
            ret = HTTPCli_readRawResponseBody(&cli, data, sizeof(data) - 1);logg("***************\n","");
            logStrInt("*response body is  %s and ret=%i", "", data, ret);
            memset(data, 0, 1025);memset(ftpCmd, 0, 200);
        }
    
        strcpy(ftpCmd, "PWD \r\n");
        ret = HTTPCli_sendRequestBody(&cli, ftpCmd, sizeof(ftpCmd));
        if (ret < 0)
        {
            logStrInt("***ERROR*** - sendRequestBody reading file %s failed ret=%i",
                      "", ftpCmd, ret);
            return ret;
        }
        else
        {
            ret = HTTPCli_readRawResponseBody(&cli, data, sizeof(data) - 1);logg("***************\n","");
            logStrInt("*response body is  %s and ret=%i", "", data, ret);
            memset(data, 0, 1025);memset(ftpCmd, 0, 200);
        }
    
        strcpy(ftpCmd, "TYPE I\r\n");
        ret = HTTPCli_sendRequestBody(&cli, ftpCmd, sizeof(ftpCmd));
        if (ret < 0)
        {
            logStrInt("***ERROR*** - sendRequestBody reading file %s failed ret=%i",
                      "", ftpCmd, ret);
            return ret;
        }
        else
        {
            ret = HTTPCli_readRawResponseBody(&cli, data, sizeof(data) - 1);logg("***************\n","");
            logStrInt("*response body is  %s and ret=%i", "", data, ret);
            memset(data, 0, 1025);memset(ftpCmd, 0, 200);
        }
    
    return ret;
    }
    
    #define CERT_WRITE_CHUNK_SIZE 4096
    int32_t writeCert(uint8_t *data, const int len);
    
    bool ftp_debug = true;
    extern const int sizeof_ca_cert1,sizeof_ca_cert;
    extern uint8_t ca_cert1[],ca_cert[];
    
    #define SL_SSL_CA_CERT_FILE_NAME "/testcacert.der"
    
    struct sockaddr_in g_addr1 = { 0 }, g_addr2={0};
    HTTPCli_Struct cli,cli1;
    
    /*
     *  ======== base64Decode ========
     *  Returns the decoded value
     */
    static uint8_t base64Decode(uint8_t ch)
    {
        uint8_t ret = 0;
        if (ch >= 'A' && ch <= 'Z') {
            ret = ch - 'A';
        }
        else if (ch >= 'a' && ch <= 'z') {
            ret = ch - 'a' + 26;
        }
        else if (ch >= '0' && ch <= '9') {
            ret = ch - '0' + 52;
        }
        else if (ch == '+') {
            ret = 62;
        }
        else if (ch == '/') {
            ret = 63;
        }
    
        return (ret);
    }
    int CertConv_pem2der(const uint8_t *pem, uint32_t plen, uint8_t **der,
             uint32_t *dlen)
    {
        int value = 0;
        int i;
        int j;
        int padZero = 0;
        uint8_t *derPtr;
        uint32_t derLen;
    
        if ((pem == NULL) || (der == NULL)) {
            return (-1);
        }
    
        for (i = plen; pem[i - 1] == '='; i--) {
            padZero++;
        }
    
        /* Base64 decode: 4 characters to 3 bytes */
        derLen = (plen / 4) * 3;
        derPtr = (uint8_t *) malloc(derLen);
        if (!derPtr) {
            return (-1);
        }
    
        for (i = 0, j = 0; (i + 3) < plen && (j + 2) < derLen; i += 4, j += 3) {
            value = (base64Decode(pem[i]) << 18)
                    + (base64Decode(pem[i + 1]) <<  12)
                    + (base64Decode(pem[i + 2]) << 6)
                    + base64Decode(pem[i + 3]);
    
            derPtr[j]     = (value >> 16) & 0xFF;
            derPtr[j + 1] = (value >> 8) & 0xFF;
            derPtr[j + 2] = value & 0xFF;
        }
    
        /* Actual length of buffer filled */
        *dlen = derLen - padZero;
        *der = derPtr;
    
        return (0);
    }
    
    int createFtpSocket(char *ipAddress, int portNr) // this is called and then I am sending the AUTH TLS command//// but I am not able to connect
    {
        //////////////////  real ftps code using sl apis
    
               int valread, status;
               char ftpCmd[50] = {0};
               char ftpResp[500] = {0};
    
    
               int ret = 0;
              uint8_t *der = NULL;
              uint32_t len;
    
             ret = CertConv_pem2der(ca_cert, sizeof_ca_cert, &der, &len);
    
              int val = writeCert(der, len);
               if(!val) logg("cert file created successfully\n", "");
               else logg("***Error*** - cert file can not be created\n", "");
    
                int sock = sl_Socket(SL_AF_INET,SL_SOCK_STREAM, SL_SEC_SOCKET);
    			
    			/***NOTE: If I use SL_SEC_SOCKET -370 comes and If I use IPPROTO_IP TLS doesnot work******/
    			/**** If using IPPROTO_IP, it connects but while executing AUTH TLS command, nothing happens *****/
    
             //   int sock = sl_Socket(SL_AF_INET,SL_SOCK_STREAM, IPPROTO_IP/**/);
                if (sock == -1) {
                     logg("ftp: ***ERROR*** - socket not created.","");
                     sock = 0;goto sockCleanup;
                 } else {
                     if (ftp_debug) logStr("ftp: socket %s created successfully.","",ipAddress);
                 }
                char selfCertFileName[] = SL_SSL_CA_CERT_FILE_NAME;
                SlSockSecureMethod method;
    
               unsigned long cipher =  SL_SEC_MASK_SECURE_DEFAULT ;
    
                method.secureMethod = SL_SO_SEC_METHOD_TLSV1_2;  // security method we want to use
                ret = sl_SetSockOpt(sock, SL_SOL_SOCKET, SL_SO_SECURE_MASK, &cipher, sizeof(cipher));
    
                 ret = sl_SetSockOpt(sock, SL_SOL_SOCKET, SL_SO_SECMETHOD, &method, sizeof(method));
    
                ret= sl_SetSockOpt(sock, SL_SOL_SOCKET, SL_SO_SECURE_FILES_CA_FILE_NAME, selfCertFileName,
                                   strlen(selfCertFileName));
    
               struct sockaddr_in serv_addr;
               memset(&serv_addr, 0, sizeof(serv_addr));
               serv_addr.sin_family = AF_INET;
               serv_addr.sin_port = htons(portNr);
    
               if (HTTPCli_initSockAddr((struct sockaddr *)&serv_addr, ipAddress, 0) < 0) {
                   logg("ftp: ***ERROR*** - address not resolved.","");
                   sock = 0;goto sockCleanup;
               }
    
               _i16 x = connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
               if (x< 0) { // akhilesh
               logStrInt("ftp: ***ERROR*** - connect failed ip %s port %d - quitting.","",ipAddress,portNr);
               logInt(" \nreturn value is %d ", "", x);
                sock = 0;goto sockCleanup;
              } else {
                 if (ftp_debug) logStr("ftp: successfully connected to ftp server %s","",ipAddress);
               }
               if (portNr == 21) {
                   valread = recv(sock, ftpResp, sizeof(ftpResp)-1, 0);
                   g_tuneBuf[valread-2] = 0;
                   if (ftp_debug) logIntStr("ftp welcome msg [%d] %s","", valread, ftpResp);
               }
    
               return sock;
    
               sockCleanup:
                   if (sock > 0) {
                       close(sock);
                   }
                   return sock;
    }
    
    #ifdef NET_SL
    int32_t writeCert(uint8_t *data, const int len)
    {
        int32_t fHdl, file;
        uint32_t status;
        const uint8_t filename[] = SL_SSL_CA_CERT_FILE_NAME;
        uint32_t offset, token;
        uint32_t writeLen;
    
        fHdl = sl_FsOpen(filename, FS_MODE_OPEN_CREATE( len, _FS_FILE_PUBLIC_WRITE), NULL, &file);
        if (fHdl >= 0)
        {
            offset = 0;
            do
            {
                if (len < CERT_WRITE_CHUNK_SIZE)
                {
                    writeLen = len;
                }
                else
                {
                    writeLen = CERT_WRITE_CHUNK_SIZE;
                }
                status = sl_FsWrite(file, offset, &(data[offset]), writeLen);
                if (!status)
                {
                    logInt(" error value is %d ", "", status);
                    return status;
                }
                offset += writeLen;
            }
            while (offset < len);
    
            sl_FsClose(file, NULL, NULL, 0);
            return 0;
        }
        else
        {
            return -1;
        }
    }
    #endif
    

  • Akhilesh,

    Can you get a sniffer capture of this issue and provide it to us? Error -370 means you have an error in what protocols are being supported for the connection. For example, the simplelink device could only do TLS1.0 and the server requires TLS1.1. The sniffer capture should tell us more info.

    Looking at your code, i don't see you specifying the protocol or cipher suite. Can you try adding this? Roger Monk has a good explanation of cipher suites here: https://e2e.ti.com/support/wireless-connectivity/wifi/f/968/t/636342?CC3200-Problem-with-cipher-suit-in-HTTPS-Connection

    BR,

    Vince

  •  Hi Vince, I tried all the cipher suites available in cc3100. There are two things-

    1. I tried to connect on port 21 in explicit  FTP mode and I am getting -370. I am not getting this error in https.

    2. I tried on port 990 in implicit FTP mode and tried all the cipher suits using simplelink and getting error either -340 or -155. 

    I attaching the wireshark logs of port 991 connection. Please check. 

    192.168.0.172 is the ftp client having simple link and 192.168.0.138 is the ftps server running on my local machine. 

    I saw that post too. 

    Can you explain why I am getting different errors when I change the port no?

    Not able to attach Wireshark logs *********** attaching screen shot.... 

  • Akhilesh,

    Try sending me a message with the wireshark capture. If open that capture, and dig into the details of the reset, it should tell you why the device reset the connection.

    For the ports, I don't see a reason why our device would care, but for the server, ports are used to define what kind of traffic is expected. Be sure you use a port that is open for that connection. Can you test your FTP locally with a specific port and verify a working one?

    BR,

    Vince

  • Vince,

    All other local ftps clients are working I checked that. I am sending you Wireshark capture in the message. I am getting -155 always and the device is sending the reset. 

    Please check. It's a long time I am stuck at this. I am using port n0 990.

    Thanks

  • Akhilesh,

    If you run these individually, does the software work? Or are you still trying to do the two secure sockets at once?

  • No. I run individually. What I saw on port 21, i am getting -370 and on port 990, -155.

    I run only 1 at a time by editing the code.

    Didi you try at your end?

  • Akhilesh,

    Your using CC3100 or CC3120?

    BR,

    Vince 

  • Hi Vince,

    I am using cc3100. Can i enable nwp logs there?

  • There is no pinmux.c file in my project. 

  • HI Vince,

    I am able to use implicit ftps on port no 990 using httpcli library where handshake happens while connecting to server. 

    Using the same library, can I do the handshake explicitly after connecting? I dont want handshake while connecting. I want it to happen after sending AUTH TLS command to server. How can I do this? This is what I need for explicit ftps. 

    Thanks

  • Hi Vince, 

    I can't do explicit ftps in cc3100. I just came to know and that's why this error was coming. Anyway, implicit ftps is working. Can I use wolfssl library with cc3100? 

  • Akhilesh,

    No you can't use wolfssl on our device.

    BR,

    Vince 

  • Hi Vince,

    I think he could be able use 3rd party SSL/TLS library with non secured TCP socket from CC3100 and transparently encrypt at host side. I don't see any technical reason which will prevent this type of use. Because we talk about TLS/SSL not IPsec.

    Jan

  • Jan,

    This is true, but we cannot support this effort. 

    BR,

    Vince 

  • Hi Vince,

    I am successfully able to use wolfssl with cc3100. I can do explicit Ftps now.

    Thanks