Correct closing connection & cleanup SSL

Hello.
I use MBEDTLS with LwIP and FreeRTOS. Project generated in CubeMX, STM32 microcontroller.

I also took as a basis the examples provided by ST, and also looked at the ssl-client2.c file, which is in the repository on Github.

My mode of operation is:

  1. Connect to server
  2. I start the handshake process
  3. I make a GET request to the server
  4. I get an answer
  5. Disconnect from the server, calling its function Reconnect:
    uint8_t  Reconnect(void)
    {
      
      uint32_t tickstart = 0;
      
      do {
        
        error_dbg.ssl_close_notify++;
        ret = mbedtls_ssl_close_notify( &ssl );
        
      }while( ret == MBEDTLS_ERR_SSL_WANT_WRITE );    
      
      mbedtls_net_free(&server_fd);
      
      tickstart = xTaskGetTickCount();
      while((ret = mbedtls_ssl_session_reset(&ssl)) !=0)
      {
        
        if((xTaskGetTickCount() - tickstart) > 2500)
        {
          
          return 1; 
          
        }  
        
      }
      
      tickstart = xTaskGetTickCount();                      
      while((ret = mbedtls_ssl_set_session( &ssl, &saved_session )) != 0)
      {	
        
        if((xTaskGetTickCount() - tickstart) > 2500)
        {
          
          return 2; 
          
        }    
        
      }         
      
      return 0;
        
    }

Next, go to step 1 and the whole process repeats.

But there is a problem - after a while (30-60 minutes, and sometimes more) I see an error in the debugger: the handshake process ends with an error or time-out and I need to reset the microcontroller in order to restore the data exchange with the server.

I tried cleaning up all the SSL — like in the ssl-client2.c file, when going to the exit label. Then I re-initialize SSL and start the exchange with the server. This helps, but I noticed that after that an error in the handshake occurs very often - once every 5-7 attempts. But if you reset the microcontroller, then the first few tens of minutes of errors do not occur.

Do I close the connection to the server correctly? And how to make a complete cleaning of SSL, so that the exchange with the server happens without errors?

Hi @uchar
Thank you for your question!

It seems you are closing correct the connection.
I am assuming you are calling mbedtls_ssl_get_session() after handshake over, right?
Since you are reconnecting with a saved session, all you need to do after setting the session, is to connect to the server, and then call mbedtls_ssl_handshake(). I am assuming this is your flow, and now structure initialization is done in between.

Have you considered doing a new connection to the server, without restoring a saved session?
May I know what the error you ar ereceiving is? What is the timeout you are receiving? Are you doing a DTLS connection?

Regards,
Mbed TLS Team member
Ron

Yes, I am calling `mbedtls_ssl_get_session() after handshake :

  tickstart = xTaskGetTickCount();
  
  while((ret = mbedtls_ssl_handshake( &ssl )) != 0)
  {
    if(ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE)
    {
      return SSL_HANDSHAKE;
    }
    
    if((xTaskGetTickCount() - tickstart) > 5000){
      return SSL_HANDSHAKE_TIMEOUT;      
    }    
    
  }  
  
  
  if( ( ret = mbedtls_ssl_get_session( &ssl, &saved_session ) ) != 0 )
  {
    return SSL_GET_SESSION;
  }   

Within 5 seconds I am waiting for a response to mbedtls_ssl_handshake (& ssl)). I added this myself so that the microcontroller does not hang in this place.
Sometimes the mbedtls_ssl_handshake (& ssl)) function returns a strange error code - 0x00A5A55F or 0x00A6AC4F. But usually there is no answer, and my program leaves this section on a timeout.

Now, after this error, I completely clean and re-initialize everything, it helps, but partially. Handshake errors are still there and their number greatly increases with time. But if you reset the microcontroller, then everything will work well - the first 30-60 minutes, as I wrote earlier.

The code that I call when an error occurs:

uint8_t Shutdown(uint8_t mode)
{
  
  int ret = 0;
  
  do {
   
    ret = mbedtls_ssl_close_notify( &ssl );
    
  }while( ret == MBEDTLS_ERR_SSL_WANT_WRITE );  
  
  mbedtls_ssl_session_reset(&ssl);
  
  mbedtls_net_free( &server_fd );

  mbedtls_x509_crt_free( &cacert );
  mbedtls_ssl_free( &ssl );
  mbedtls_ssl_config_free( &conf );
  mbedtls_ctr_drbg_free( &ctr_drbg );
  mbedtls_entropy_free( &entropy );  

  return 0;
		
}

It sounds to me that you have some memory corruption, because this is not an error code returned from Mbed TLS.
Unless, these are errors returned from your bio callbacks.