cancel
Showing results for 
Search instead for 
Did you mean: 

FreeRTOS + LWIP + mbedtls failed to ssl handshake failed

Duy Tran
Associate II

Dear everyone,

I am using Nucleo-F767ZI + FreeRTOS + LWIP + mbedtls generated my STM32CubeMX (latest version).

When I use my code to connect and send data to www.google.com using HTTPS, everything works fine, however when the same code is used to connect to httpbin.org using HTTPS, the code fails in function mbedtls_ssl_handshake(&ssl) which returns code 76 (it is also the return code function mbedtls_net_recv()). The failure happens in function int mbedtls_ssl_handshake_client_step( mbedtls_ssl_context *ssl ) step MBEDTLS_SSL_SERVER_HELLO.

My code is as below:

void tcp_client_deinit(void)
{
	uart_print("Deinit\r\n");
//	mbedtls_net_free(&server_fd);
	mbedtls_ssl_free(&ssl);
	mbedtls_ssl_config_free(&conf);
	mbedtls_ctr_drbg_free(&ctr_drbg);
	mbedtls_entropy_free(&entropy);
	mbedtls_x509_crt_free(&cacert);
}
 
void tcp_client_init(void)
{
//	mbedtls_net_init(&server_fd);
 
	while ((gnetif.ip_addr.addr == 0) || (gnetif.netmask.addr == 0) || (gnetif.gw.addr == 0))
	{
 
	}
#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
	mbedtls_memory_buffer_alloc_init(alloc_buf, sizeof(alloc_buf));
#endif
 
	uart_print("DHCP OK!\r\n");
 
	mbedtls_ssl_init(&ssl);
	mbedtls_ssl_config_init(&conf);
	mbedtls_x509_crt_init(&cacert);
	mbedtls_ctr_drbg_init(&ctr_drbg);
 
	uart_print("Seeding the random number generator...\r\n");
 
	mbedtls_entropy_init(&entropy);
	if (0 != mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, (const unsigned char *)pers, strlen(pers)))
	{
		uart_print("Seeding random number generator failed!\r\n");
		tcp_client_deinit();
	}
 
	uart_print("Loading the CA root certificate...\r\n");
	if (0 >  mbedtls_x509_crt_parse(&cacert, (const unsigned char *)ca, calen))
	{
		uart_print("Loading CA root certificate failed\r\n");
		tcp_client_deinit();
	}
 
	mbedtls_ssl_set_bio(&ssl, &server_fd, mbedtls_net_send, mbedtls_net_recv, NULL);
 
	uart_print("TCP client initialized!\r\n");
}
 
 
/**
  * @brief  Connects to the TCP echo server
  * @param  None
  * @retval None
  */
void tcp_client_handle(void)
{
	s32_t ret;
	u32_t verify_flags;
	u32_t time_out = 0;
	u8_t verify_buf[256];
 
	uart_print("Connecting to: %s Port: %s\r\n", SERVER_NAME, SERVER_PORT);
	time_out = osKernelSysTick();
	while (0 != mbedtls_net_connect(&server_fd, SERVER_NAME, SERVER_PORT, MBEDTLS_NET_PROTO_TCP))
	{
		if ((uint32_t)(osKernelSysTick() - time_out) > 8192)
		{
			uart_print("Failed to connect to server\r\n");
			return;
		}
	}
	uart_print("Network successfully connected!\r\n");
 
	if (0 != mbedtls_ssl_config_defaults(&conf, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT))
	{
		uart_print("SSL config failed\r\n");
		return;
	}
	uart_print("SSL successfully configured!\r\n");
 
    mbedtls_ssl_conf_authmode(&conf, MBEDTLS_SSL_VERIFY_OPTIONAL);
    mbedtls_ssl_conf_ca_chain(&conf, &cacert, NULL);
    mbedtls_ssl_conf_rng(&conf, mbedtls_ctr_drbg_random, &ctr_drbg);
 
    if (0 != mbedtls_ssl_setup(&ssl, &conf))
    {
		uart_print("SSL setup failed\r\n");
		return;
    }
 
    if (0 != mbedtls_ssl_set_hostname(&ssl, SERVER_NAME))
    {
    	uart_print("Hostname setup failed\r\n");
    	return;
    }
 
    uart_print("Performing handshake\r\n");
    time_out = osKernelSysTick();
    while (0 != (ret = mbedtls_ssl_handshake(&ssl)))
    {
		if ((uint32_t)(osKernelSysTick() - time_out) > 8192)
		{
			uart_print("Handshake failed, error %d\r\n", ret);
			return;
//			break;
		}
    }
    uart_print("Handshake succeeded\r\n");
 
    uart_print("Verifying peer X.509 certificate...\r\n");
    if (0 != (verify_flags = mbedtls_ssl_get_verify_result(&ssl)))
    {
    	mbedtls_x509_crt_verify_info((char *)verify_buf, sizeof(verify_buf), "  ! ", verify_flags);
    	uart_print("Failed to verify certificate, reason: %s\r\n", verify_buf);
//    	return;
    }
    else
    {
    	uart_print("Certificate verified\r\n");
    }
 
    uart_print(" > Write to the server\r\n");
    sprintf((char *)data_buffer, "%s", GET_REQUEST);
    time_out = osKernelSysTick();
    while (0 > mbedtls_ssl_write(&ssl, data_buffer, strlen((const char *)data_buffer)))
    {
		if ((uint32_t)(osKernelSysTick() - time_out) > 8192)
		{
			uart_print("Write failed\r\n");
			return;
		}
    }
 
    memset(data_buffer, 0, SIZE(data_buffer));
 
    uart_print(" < Read from the server\r\n");
    time_out = osKernelSysTick();
    while (0 != mbedtls_ssl_read(&ssl, data_buffer, SIZE(data_buffer)))
    {
		if ((uint32_t)(osKernelSysTick() - time_out) > 8192)
		{
			uart_print("Read failed\r\n");
			return;
		}
    }
    uart_print("%s\r\n", data_buffer);
 
    uart_print("Closing connection\r\n");
    time_out = osKernelSysTick();
    while (0 != mbedtls_ssl_close_notify(&ssl))
    {
		if ((uint32_t)(osKernelSysTick() - time_out) > 8192)
		{
			uart_print("Failed to close connection\r\n");
			return;
		}
    }
 
    uart_print("Reset connection\r\n");
    time_out = osKernelSysTick();
    while (0 != (ret = mbedtls_ssl_session_reset(&ssl)))
    {
		if ((uint32_t)(osKernelSysTick() - time_out) > 8192)
		{
			uart_print("Connection reset failed\r\n");
			return;
		}
    }
}

Can you give me any advises on how to fix this issue or what is the cause?

Thanks and best regards,

Duy Tran

1 ACCEPTED SOLUTION
4 REPLIES 4
Guillaume K
ST Employee

Hi

have you put the root certificate for httpbin.org in cacert ? ( used in line 85: mbedtls_ssl_conf_ca_chain(&conf, &cacert, NULL) )

Hi @Guillaume K​ ,

Yes I did. I exported the root certificate from the browser.

Thanks and best regards,

Duy Tran

Duy Tran
Associate II

Hello,

Does ST have any examples on this? May be I can just read and follow ST's examples.