Skip to main content
Duy Tran
Associate III
September 17, 2020
Solved

FreeRTOS + LWIP + mbedtls failed to ssl handshake failed

  • September 17, 2020
  • 4 replies
  • 3847 views

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

This topic has been closed for replies.

4 replies

Guillaume K
ST Employee
September 17, 2020

Hi

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

Duy Tran
Duy TranAuthor
Associate III
September 17, 2020

Hi @Guillaume K​ ,

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

Thanks and best regards,

Duy Tran

Duy Tran
Duy TranAuthor
Associate III
September 22, 2020

Hello,

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

Guillaume K
Guillaume KBest answer
ST Employee
September 23, 2020