Integration of SSL in coreHTTP

Hello,
I recently used FreeRTOSplus TCP with coreHTTP to make request to open HTTP server.
I am trying to integrate any SSL option that is available with with coreHTTP to make HTTPS request to available server. I tried integrating MbedTLS but I am getting too many config errors (for MbedTLS config) while integrating.
Is there any example available for STM32 using HTTPS client with ported any SSL library?

Hi @ashvajit

These are coreHTTP demos with FreeRTOS-Plus-TCP : coreHTTP_Windows_Simulator.
Some details are present over this webpage as well.

Can you please check if these works as a reference.

Thank You

Hi,
I have already checked out those.
If I just wanted to do certificate-based authentication and using a private key, is this possible with mbedtls ?
Currently I am getting build errors

Error[Li005]: no definition for “taskDISABLE_INTERRUPTS” [referenced from C:\Projects\IAR\Eth_FreeRTOS_F4\EWARM\Eth_FreeRTOS_F4\Obj\network_transport_10444936529919355836.dir\transport_mbedtls.o]

Currently I am initializing my HTTPS as :

int32_t connectToServer(NetworkContext_t *pNetworkContext, const char *host, const unsigned int port,NetworkCredentials_t* xNetworkCredentials) {

    return TLS_FreeRTOS_Connect(pNetworkContext,host,port,
                                           xNetworkCredentials,                                 TRANSPORT_SEND_RECV_TIMEOUT_MS,TRANSPORT_SEND_RECV_TIMEOUT_MS);
}
HTTPResponse_t request(const TransportInterface_t *pTransportInterface,
                                const char *pMethod,
                                size_t methodLen,
                                const char *pHost,
                                size_t hostLen,
                                const char *pPath,
                                size_t pathLen) {
  HTTPStatus_t httpStatus = HTTPSuccess;
  HTTPRequestInfo_t requestInfo = {0};
  HTTPResponse_t response = {0};
  HTTPRequestHeaders_t requestHeaders = {0};

  requestInfo.pMethod = pMethod;
  requestInfo.methodLen = methodLen;
  requestInfo.pHost = pHost;
  requestInfo.hostLen = hostLen;
  requestInfo.pPath = pPath;
  requestInfo.pathLen = pathLen;
  requestInfo.reqFlags = HTTP_REQUEST_KEEP_ALIVE_FLAG;

  requestHeaders.pBuffer = userBuffer;
  requestHeaders.bufferLen = USER_BUFFER_LENGTH;

  httpStatus = HTTPClient_InitializeRequestHeaders(&requestHeaders, &requestInfo);

  if (httpStatus == HTTPSuccess) {
    my_response.pBuffer = response_buff;
    my_response.bufferLen = USER_BUFFER_LENGTH;

    httpStatus = HTTPClient_Send( pTransportInterface,
                                  &requestHeaders,
                                  0, // ( uint8_t * ) REQUEST_BODY,
                                  0, // REQUEST_BODY_LENGTH,
                                  &my_response,
                                  0 );
  } else {

  }

  return response;
}

void http_get() {
  int32_t returnStatus = pdTRUE;
  BaseType_t returnstat;
  typedef struct NetworkContext NetworkContext_t ;
  NetworkContext_t networkContext = {0};
    TransportInterface_t transportInterface = {0};

  TlsTransportParams_t xTlsTransportParams = { 0 };
  networkContext.pParams = &xTlsTransportParams;
    NetworkCredentials_t xNetworkCredentials = 
    {
      .pRootCa = "certificate/tls_cert.crt",
      .rootCaSize = strlen("certificate/tls_cert.crt"),
    };

   while( pdPASS != connectToServer(&networkContext,HOST_NAME, HTTP_PORT, &xNetworkCredentials) )
            {
                vTaskDelay( pdMS_TO_TICKS( 5000U ) );
            }
  transportInterface.pNetworkContext = &networkContext;
  transportInterface.recv = TLS_FreeRTOS_recv;
  transportInterface.send = TLS_FreeRTOS_send;

  
  uint16_t host_name_len = strlen(HOST_NAME);
  uint8_t path_len = strlen(HOST_URI);
   
  HTTPResponse_t response = request(&transportInterface, "GET", 3, HOST_NAME, host_name_len, HOST_URI,path_len);

  TLS_FreeRTOS_Disconnect(&networkContext);
}

Also, Is my mbedtls_config file properly configured with network_transport module ?
mbedtls_config.h (110.5 KB)

taskDISABLE_INTERRUPTS should get defined to portDISABLE_INTERRUPTS: FreeRTOS-Kernel/include/task.h at 625b24a104dd901d86759668b6b272590d154308 · FreeRTOS/FreeRTOS-Kernel · GitHub. Are you not including FreeRTOS.h and task.h in transport_mbedtls.c?

Thanks @aggarg,
It seems like it was not being included in the transpport_mbedtls, mbedtls_bio_tcp_sockets source files.
Build errors are resolved but I am not able to connect to a HTTPS server due to error while initializing MbedTLS : MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED and last I was able to debug up to mbedtls_ctr_drbg_reseed_internal function which might be due to
such as insufficient entropy input, hardware issues, or misconfiguration.
Is there any mbedtls configuration aligned with FreeRTOS or STM32F4 that I can verify with?
I have attached my config file here.

This repo is for STM32U5 and uses mbedTLS and you can look at the mebedTLS config file there. As this error is related to mbedTLS, I’d also recommend to post mbedTLS forums.

I resolved the errors related to mbedtls and now I am getting TLS_TRANSPORT_INVALID_CREDENTIALS.
I have modified the way I was giving credentials.
Is this the proper way to provide credentials ?

#define rootCA_Certificate \
    "-----BEGIN CERTIFICATE-----\n" \
   "MIIDQTCCAimgAwIBAgITBm....yfz5mFo6IQ6XU5MsI\n" \
    "-----END CERTIFICATE-----\n"

I have truncated the content in this post, but it is in the single line. this is taken from the provided link in the example certificate.

  const char* Root_CA_cert = rootCA_Certificate;
    NetworkCredentials_t xNetworkCredentials = 
    {
      .pRootCa = Root_CA_cert,
      .rootCaSize = sizeof(Root_CA_cert),
      .pClientCert = NULL,
      .clientCertSize = 0,
      .pPrivateKey = NULL,
      .privateKeySize = 0,
    };

is it okay to just use root CA certificate for authentication?

Yes, that looks correct.

If the server you are connecting to, supports server only authentication, then it is okay. If it requires mutual authentication, you need client cert and key as well.

Can you step through and see where is this error returned from?

Yes, earlier it was due to calloc failure while allocating the memory.
I referred to mbedtls documentation and used the freertos functions pvPortmalloc and pvPortfree as dynamic allocation alternative to standard functions.
But now I am getting an error MBEDTLS_ERR_ASN1_OUT_OF_DATA from asn1parse.c

Also, I replaced sizeof with strlen as it was not providing accurate string length.

and I did some work around for detecting pem file as string length was not including null terminator in x509_crt.c .

#if defined(MBEDTLS_PEM_PARSE_C)
    if (buflen != 0 && buf[buflen/*-1*/] == '\0' &&
        strstr((const char *) buf, "-----BEGIN CERTIFICATE-----") != NULL) {
        buf_format = MBEDTLS_X509_FORMAT_PEM;
    }
/* 1 rather than 0 since the terminating NULL byte is counted in */
        while (buflen > 0/*1*/) { 
            size_t use_len;
            mbedtls_pem_init(&pem);

            /* If we get there, we know the string is null-terminated */
            ret = mbedtls_pem_read_buffer(&pem,
                                          "-----BEGIN CERTIFICATE-----",
                                          "-----END CERTIFICATE-----",
                                          buf, NULL, 0, &use_len);

            if (ret == 0) {
                /*
                 * Was PEM encoded
                 */
                buflen -= use_len;
                buf += use_len;
            }

I tried using DER format certificate from by converting it using an online tool but am still stuck at MBEDTLS_ERR_ASN1_OUT_OF_DATA from asn1parse.c

What is this workaround? Is it adding 1 to include NULL character too?

This is very mbedTLS specific and I’d recommend asking on their forums.

Yes, otherwise it won’t let me pass the condition

Yes, I’ll do that. :slight_smile:

I’ve made progress in resolving previous errors by reverting certain changes.
Additionally, I managed to address another issue of entropy resource by implementing a Random Number Generator (RNG) from STM32 within the mbed_Entropy_poll function. However, this led to a conflict with xApplicationGetRandomNumber, which I overcame with a workaround.
I’m also utilizing the calloc and free functions provided by FreeRTOS.

Despite these solutions, I’m encountering a persistent challenge: my STM32 is unable to connect to the server, failing at the TLS handshake stage while awaiting the ACK for the Hello Client message.

I suspect the problem may lie in my implementation of mbedtls within FreeRTOS. Notably, after processing a single request, my code becomes stuck at

heapVALIDATE_BLOCK_POINTER( pxLink )

within the vPortFree function.

For further diagnosis, I ran the coreHTTP mutual auth windows simulator and tested my mbedtls_config file, which functioned correctly, suggesting the issue may not be configuration related.

Any insights or suggestions you could provide would be greatly appreciated.
My implementation

This means that the pointer you are passing to vPortFree is not valid - FreeRTOS-Kernel/portable/MemMang/heap_4.c at main · FreeRTOS/FreeRTOS-Kernel · GitHub. Can you examine the callstack and see where is vPortFree called from and why is it passing incorrect pointer? If it is happening in mbedTLS, you can log the allocated pointers here to confirm the a valid pointer is being freed.

I also saw this implementation of mbedtls_hardware_poll. Why can you not call HAL_RNG_GenerateRandomNumber directly in this function?

Hi,
looked at the call stack it’s the entropy free function. That is causing this issue. Does that mean during initialization it has not been configured properly?
Screenshot 2024-03-28 161034

I have tried that earlier also, but it is working now.

Glad you worked it out!

I mean the RNG is working but I am still facing memmory and handshake issue.

Did you provide the implementation of mbedtls_free and that is how it is calling vPortFree? If yes, you must have provided an allocation function too. Can you share both of them? Also, what is the value of ptr in vPortFree?

Yes, I had provided after the entropy initialization. But now I have fixed it and updated the repo.

    mbedtls_platform_set_calloc_free(pvPortCalloc,vPortFree);
    /* Establish a TCP connection with the server. */
    if( returnStatus == TLS_TRANSPORT_SUCCESS )
    {
        pTlsTransportParams = pNetworkContext->pParams;

        /* Initialize tcpSocket. */
        pTlsTransportParams->tcpSocket = NULL;

I am at least not blocked in vPortFree function, But I did face MBEDTLS_ERR_X509_ALLOC_FAILED error then I increased heap size provided and got out of it.
I am still not able to connect now as I am stuck in the next step while parsing the certificate,
Screenshot 2024-03-29 164321
and error is MBEDTLS_SSL_ALERT_MSG_BAD_CERT
But I used same certificates with Win Simulator and those are working with it. .

Hey, I got TLS working there was problem in the URL, I changed it and its working now.
Thanks for your support !! :smiley: :smiley:

Glad that it worked for you! Thank you for reporting back.