2020-09-17 03:29 AM
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
Solved! Go to Solution.
2020-09-23 06:28 AM
2020-09-17 05:21 AM
Hi
have you put the root certificate for httpbin.org in cacert ? ( used in line 85: mbedtls_ssl_conf_ca_chain(&conf, &cacert, NULL) )
2020-09-17 08:48 AM
Hi @Guillaume K ,
Yes I did. I exported the root certificate from the browser.
Thanks and best regards,
Duy Tran
2020-09-22 09:47 AM
Hello,
Does ST have any examples on this? May be I can just read and follow ST's examples.
2020-09-23 06:28 AM
see example in STM32 Cube F7 package: