2019-08-26 04:42 PM
I am trying to implement a simple MBEDTLS communication firmware with my STM32F417VE.
I am using STM32CubeMX as configuration tool and Atollic 9.3.0 as IDE. MBEDTLS, LWIP, FREERTOS and ETHERNET are all set from the STM32Cube.
I am trying to perform a simple connection with the website "os.mbed.org" port 443.
Attached is my mbedtls_conf.h file generated from Cube:
Below is my StartDefaultTask used for this test:
#define SERVER_PORT "443"
#define SERVER_NAME "os.mbed.com"
#define GET_REQUEST "GET / HTTP/1.0\r\n\r\n"
static void my_debug( void *ctx, int level,
const char *file, int line, const char *str )
{
((void) level);
printf( "%s:%04d: %s", file, line, str );
}
void StartDefaultTask(void const * argument)
{
ip4_addr_t primaryDnsServer;
int ret;
int len;
uint32_t flags;
unsigned char buf[1024];
/* MBEDTLS */
mbedtls_net_context server_fd;
mbedtls_entropy_context entropy;
mbedtls_ctr_drbg_context ctr_drbg;
mbedtls_ssl_context ssl;
mbedtls_ssl_config conf;
mbedtls_x509_crt cacert;
const char *pers = "ssl_client1";
/* MX_LWIP_Init() is generated within mbedtls_net_init() function in net_cockets.c file */
/* Up to user to call mbedtls_net_init() function in MBEDTLS initialization step */
/* init code for USB_DEVICE */
MX_USB_DEVICE_Init();
/* Up to user define the empty MX_MBEDTLS_Init() function located in mbedtls.c file */
MX_MBEDTLS_Init();
printf("mbedtls_net_init\n");
mbedtls_net_init( &server_fd );
/* Configurando interface de rede */
printf("Waiting network interface\n");
osDelay(3000);
/* Configurando o DNS */
printf("Configurando DNS\n");
IP4_ADDR(&primaryDnsServer,8,8,8,8);
dns_setserver(0, &primaryDnsServer);
printf("mbedtls_ssl_init\n");
mbedtls_ssl_init( &ssl );
printf("mbedtls_ssl_config_init\n");
mbedtls_ssl_config_init( &conf );
printf("mbedtls_x509_crt_init\n");
mbedtls_x509_crt_init( &cacert );
printf("mbedtls_ctr_drbg_init\n");
mbedtls_ctr_drbg_init( &ctr_drbg );
printf("mbedtls_entropy_init\n");
mbedtls_entropy_init( &entropy );
printf("mbedtls_ctr_drbg_seed\n");
if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy,
(const unsigned char *) pers,
strlen( pers ) ) ) != 0 ) {
printf( " failed\n ! mbedtls_ctr_drbg_seed returned %d\n", ret );
goto exit;
}
printf( "Connecting to tcp/%s/%s...\n", SERVER_NAME, SERVER_PORT );
printf("mbedtls_net_connect\n");
if( ( ret = mbedtls_net_connect( &server_fd, SERVER_NAME,
SERVER_PORT, MBEDTLS_NET_PROTO_TCP ) ) != 0 ) {
printf( " failed\n ! mbedtls_net_connect returned %d\n\n", ret );
goto exit;
}
printf("mbedtls_ssl_config_defaults\n");
if( ( ret = mbedtls_ssl_config_defaults( &conf,
MBEDTLS_SSL_IS_CLIENT,
MBEDTLS_SSL_TRANSPORT_STREAM,
MBEDTLS_SSL_PRESET_DEFAULT ) ) != 0 ) {
printf( " failed\n ! mbedtls_ssl_config_defaults returned %d\n\n", ret );
goto exit;
}
printf("mbedtls_ssl_conf_authmode\n");
mbedtls_ssl_conf_authmode( &conf, MBEDTLS_SSL_VERIFY_OPTIONAL );
printf("mbedtls_ssl_conf_ca_chain\n");
mbedtls_ssl_conf_ca_chain( &conf, &cacert, NULL );
printf("mbedtls_ssl_conf_rng\n");
mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg );
printf("mbedtls_ssl_conf_dbg\n");
mbedtls_ssl_conf_dbg( &conf, my_debug, stdout );
printf("mbedtls_ssl_setup\n");
mbedtls_debug_set_threshold(4);
if( ( ret = mbedtls_ssl_setup(&ssl, &conf)) != 0) {
printf( " failed\n ! mbedtls_ssl_setup returned %d\n\n", ret );
goto exit;
}
printf("mbedtls_ssl_set_hostname\n");
if ((ret = mbedtls_ssl_set_hostname(&ssl,SERVER_NAME)) != 0) {
printf( " failed\n ! mbedtls_ssl_set_hostname returned %d\n\n", ret );
goto exit;
}
printf("mbedtls_ssl_set_bio\n");
mbedtls_ssl_set_bio( &ssl, &server_fd, mbedtls_net_send, mbedtls_net_recv, NULL );
printf( " ok\n" );
printf(" . Performing the SSL/TLS handshake...\n");
while ((ret = mbedtls_ssl_handshake(&ssl)) != 0 ) {
if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE ) {
printf( " failed\n ! mbedtls_ssl_handshake returned -0x%x\n\n", -ret );
goto exit;
}
}
printf( " ok\n" );
/*
* 5. Verify the server certificate
*/
printf( " . Verifying peer X.509 certificate...\n" );
/* In real life, we probably want to bail out when ret != 0 */
printf("mbedtls_ssl_get_verify_result\n" );
if ((flags = mbedtls_ssl_get_verify_result(&ssl)) != 0) {
char vrfy_buf[512];
printf( " failed\n" );
mbedtls_x509_crt_verify_info( vrfy_buf, sizeof( vrfy_buf ), " ! ", flags );
printf( "%s\n", vrfy_buf );
goto exit;
} else {
printf( " ok\n" );
}
/*
* Write the GET request
*/
printf( " > Write to server:" );
len = sprintf( (char *) buf, GET_REQUEST );
while( ( ret = mbedtls_ssl_write( &ssl, buf, len ) ) <= 0 ) {
if( ret != 0 ) {
printf( " failed\n ! write returned %d\n", ret );
goto exit;
}
}
len = ret;
printf( " %d bytes written\n\n%s\n", len, (char *) buf );
/*
* Read the HTTP response
*/
printf( " < Read from server:\n" );
do {
len = sizeof( buf ) - 1;
memset( buf, 0, sizeof( buf ) );
ret = mbedtls_ssl_read( &ssl, buf, len );
if( ret <= 0 )
{
printf( "failed\n ! ssl_read returned %d\n", ret );
break;
}
len = ret;
printf( " %d bytes read\n%s", len, (char *) buf );
} while( 1 );
exit:
mbedtls_net_free( &server_fd );
mbedtls_ssl_free( &ssl );
mbedtls_ssl_config_free( &conf );
mbedtls_ctr_drbg_free( &ctr_drbg );
mbedtls_entropy_free( &entropy );
printf("Fim da execucao\n");
/* USER CODE BEGIN 5 */
/* Infinite loop */
for(;;)
{
osDelay(1);
}
/* USER CODE END 5 */
}
And finally attached there is my output:
I am not a TLS expert, and I can't understand the messages that come from the handshake. I just found out that the error is MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE. Looking at other forums, they indicate a possible lack of the following configuration: MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384. As far as I could understand from the code, it is enabled.
Does anybody can give me a hint about what am I doing wrong?
Best regards,
Flavio