Hello, I am having trouble making a TLS connection using the mbedtls library. Currently I am getting the error code 0x8100 from the function mbedtls_ssl_setup. However, I have tested an extremely large amount of stack memory and heap memory and I still get this error, which leads me to believe that the problem is elsewhere.
Below is how far I have gotten in the code. I am working my way from the TLS Demo project. I feel like I must have missed something in my setup, but it seems to match the demo. I do not need mutual authentication with the server that I am trying to reach.
static void MQTT_Task( void * pvParameters )
{
LOG_printf( ( "MQTT Task\n" ) );
uint32_t ulPublishCount = 0U, ulTopicCount = 0U;
const uint32_t ulMaxPublishCount = 5UL;
NetworkContext_t xNetworkContext = { 0 };
TlsTransportParams_t xTlsTransportParams = { 0 };
NetworkCredentials_t xNetworkCredentials = { 0 };
MQTTContext_t xMQTTContext = { 0 };
MQTTStatus_t xMQTTStatus;
TlsTransportStatus_t xNetworkStatus;
/* Remove compiler warnings about unused parameters. */
( void ) pvParameters;
/* Set the pParams member of the network context with desired transport. */
xNetworkContext.pParams = &xTlsTransportParams;
while(1) {
LOG_printf( ( "Starting Network Connection\n" ) );
prvInitializeTopicBuffers();
if( FreeRTOS_IsNetworkUp() == pdFALSE )
{
while( FreeRTOS_IsNetworkUp() == pdFALSE )
{
vTaskDelay( pdMS_TO_TICKS( 1000U ) );
LOG_printf( ( "Waiting for the network link up event...\n" ) );
}
}
xNetworkStatus = TLS_connectToServer( &xNetworkCredentials,
&xNetworkContext );
Status.TLS = xNetworkStatus;
LOG_printf( ( "Network = %d...\n", xNetworkStatus) );
}
}
static TlsTransportStatus_t TLS_connectToServer( NetworkCredentials_t * pxNetworkCredentials,
NetworkContext_t * pxNetworkContext )
{
LOG_printf( ( "TLS Connection to Server\n" ) );
TlsTransportStatus_t xNetworkStatus;
BackoffAlgorithmStatus_t xBackoffAlgStatus = BackoffAlgorithmSuccess;
BackoffAlgorithmContext_t xReconnectParams;
uint16_t usNextRetryBackOff = 0U;
TlsTransportParams_t * pTlsTransportParams = NULL;
//TlsTransportStatus_t returnStatus = TLS_TRANSPORT_SUCCESS;
BaseType_t socketStatus = 0;
BaseType_t isSocketConnected = pdFALSE, isTlsSetup = pdFALSE;
/* Set the credentials for establishing a TLS connection. */
pxNetworkCredentials->pRootCa = ( const unsigned char * ) democonfigROOT_CA_PEM;
pxNetworkCredentials->rootCaSize = sizeof( democonfigROOT_CA_PEM );
pxNetworkCredentials->disableSni = democonfigDISABLE_SNI;
BackoffAlgorithm_InitializeParams( &xReconnectParams,
mqttexampleRETRY_BACKOFF_BASE_MS,
mqttexampleRETRY_MAX_BACKOFF_DELAY_MS,
mqttexampleRETRY_MAX_ATTEMPTS );
do
{
LOG_printf( ( "TLS Loop Started\n" ) );
// ---- Error Checks ----
if( ( pxNetworkContext == NULL ) ||
( pxNetworkContext->pParams == NULL ) ||
( democonfigMQTT_BROKER_ENDPOINT == NULL ) ||
( pxNetworkCredentials == NULL ) )
return TLS_TRANSPORT_INVALID_PARAMETER;
if( ( pxNetworkCredentials->pRootCa == NULL ) )
return TLS_TRANSPORT_INVALID_PARAMETER;
// ---- Socket Connection ----
LOG_printf( ( "Connecting to Remote Socket\n" ) );
pTlsTransportParams = pxNetworkContext->pParams;
pTlsTransportParams->tcpSocket = NULL;
socketStatus = Sockets_Connect( &( pTlsTransportParams->tcpSocket ),
democonfigMQTT_BROKER_ENDPOINT,
democonfigMQTT_BROKER_PORT,
mqttexampleTRANSPORT_SEND_RECV_TIMEOUT_MS,
mqttexampleTRANSPORT_SEND_RECV_TIMEOUT_MS );
if( socketStatus != 0 )
{
LOG_printf( ( "Failed to connect to %s with error %d.",
democonfigMQTT_BROKER_ENDPOINT,
socketStatus ) );
return TLS_TRANSPORT_CONNECT_FAILURE;
}
LOG_printf( ( "Connected to Remote Socket\n" ) );
// ---- TLS Connection MbedTLS ----
TlsTransportStatus_t TLS_Status = TLS_TRANSPORT_SUCCESS;
mbedtls_threading_set_alt( mbedtls_platform_mutex_init,
mbedtls_platform_mutex_free,
mbedtls_platform_mutex_lock,
mbedtls_platform_mutex_unlock );
if(TLS_Status != TLS_TRANSPORT_SUCCESS) {
LOG_printf( ( "mbedTLS not initalized...\n" ) );
return TLS_TRANSPORT_CONNECT_FAILURE;
}
// ---- SSL ----
LOG_printf( ( "SSL Connection\n" ) );
TlsTransportParams_t * pTlsTransportParams = NULL;
TlsTransportStatus_t returnStatus = TLS_TRANSPORT_SUCCESS;
int32_t mbedtlsError = 0;
configASSERT( pxNetworkContext != NULL );
configASSERT( pxNetworkContext->pParams != NULL );
configASSERT( democonfigMQTT_BROKER_ENDPOINT != NULL );
configASSERT( pxNetworkCredentials != NULL );
configASSERT( pxNetworkCredentials->pRootCa != NULL );
pTlsTransportParams = pxNetworkContext->pParams;
SSL_contextInit( &( pTlsTransportParams->sslContext ) );
mbedtlsError = mbedtls_ssl_config_defaults( &( pTlsTransportParams->sslContext.config ),
MBEDTLS_SSL_IS_CLIENT,
MBEDTLS_SSL_TRANSPORT_STREAM,
MBEDTLS_SSL_PRESET_DEFAULT );
if( mbedtlsError != 0 )
{
LOG_printf( ( "Failed to set default SSL configuration: mbedTLSError...") );
/* Per mbed TLS docs, mbedtls_ssl_config_defaults only fails on memory allocation. */
return TLS_TRANSPORT_INSUFFICIENT_MEMORY;
}
/* Set up the certificate security profile, starting from the default value. */
pTlsTransportParams->sslContext.certProfile = mbedtls_x509_crt_profile_default;
/* Set SSL authmode and the RNG context. */
mbedtls_ssl_conf_authmode( &( pTlsTransportParams->sslContext.config ),
MBEDTLS_SSL_VERIFY_REQUIRED );
mbedtls_ssl_conf_rng( &( pTlsTransportParams->sslContext.config ),
generateRandomBytes,
&pTlsTransportParams->sslContext );
mbedtls_ssl_conf_cert_profile( &( pTlsTransportParams->sslContext.config ),
&( pTlsTransportParams->sslContext.certProfile ) );
/* Parse the server root CA certificate into the SSL context. */
mbedtlsError = mbedtls_x509_crt_parse( &( pTlsTransportParams->sslContext.rootCa ),
pxNetworkCredentials->pRootCa,
pxNetworkCredentials->rootCaSize );
mbedtls_ssl_conf_ca_chain( &( pTlsTransportParams->sslContext.config ),
&( pTlsTransportParams->sslContext.rootCa ),
NULL );
if( mbedtlsError != 0 )
{
LogError( ( "Failed to parse server root CA certificate.\n" ) );
return TLS_TRANSPORT_INVALID_CREDENTIALS;
}
/* Enable SNI if requested. */
if( pxNetworkCredentials->disableSni == pdFALSE )
{
mbedtlsError = mbedtls_ssl_set_hostname( &( pTlsTransportParams->sslContext.context ),
democonfigMQTT_BROKER_ENDPOINT );
if( mbedtlsError != 0 )
{
LogError( ( "Failed to set server name: mbedTLSError= %s : %s.",
mbedtlsHighLevelCodeOrDefault( mbedtlsError ),
mbedtlsLowLevelCodeOrDefault( mbedtlsError ) ) );
return TLS_TRANSPORT_INTERNAL_ERROR;
}
}
/* Set Maximum Fragment Length if enabled. */
#ifdef MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
if( returnStatus == TLS_TRANSPORT_SUCCESS )
{
/* Enable the max fragment extension. 4096 bytes is currently the largest fragment size permitted.
* See RFC 8449 https://tools.ietf.org/html/rfc8449 for more information.
*
* Smaller values can be found in "mbedtls/include/ssl.h".
*/
mbedtlsError = mbedtls_ssl_conf_max_frag_len( &( pTlsTransportParams->sslContext.config ), MBEDTLS_SSL_MAX_FRAG_LEN_4096 );
if( mbedtlsError != 0 )
{
LogError( ( "Failed to maximum fragment length extension...\n") );
return TLS_TRANSPORT_INTERNAL_ERROR;
}
}
#endif /* ifdef MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
// ---- TLS Handshake ----
LOG_printf( ( "TLS Handshake\n" ) );
configASSERT( pxNetworkContext != NULL );
configASSERT( pxNetworkContext->pParams != NULL );
configASSERT( pxNetworkCredentials != NULL );
pTlsTransportParams = pxNetworkContext->pParams;
mbedtlsError = mbedtls_ssl_setup( &( pTlsTransportParams->sslContext.context ),
&( pTlsTransportParams->sslContext.config ) );
if( mbedtlsError != 0 )
{
return mbedtlsError;
}
/* These two macros MBEDTLS_SSL_SEND and MBEDTLS_SSL_RECV need to be
* defined in mbedtls_config.h according to which implementation you use.
*/
mbedtls_ssl_set_bio( &( pTlsTransportParams->sslContext.context ),
( void * ) pTlsTransportParams->tcpSocket,
mbedtls_platform_send,
mbedtls_platform_recv,
NULL );
/* Perform the TLS handshake. */
do
{
mbedtlsError = mbedtls_ssl_handshake( &( pTlsTransportParams->sslContext.context ) );
} while( ( mbedtlsError == MBEDTLS_ERR_SSL_WANT_READ ) ||
( mbedtlsError == MBEDTLS_ERR_SSL_WANT_WRITE ) );
if( mbedtlsError != 0 )
{
return TLS_TRANSPORT_HANDSHAKE_FAILED;
}
LOG_printf( ( "Reached end of loop\n" ) );
xNetworkStatus = TLS_TRANSPORT_SUCCESS;
} while( ( xNetworkStatus != TLS_TRANSPORT_SUCCESS ) && ( xBackoffAlgStatus == BackoffAlgorithmSuccess ) );
return TLS_TRANSPORT_SUCCESS;
}
static int generateRandomBytes( void * pvCtx,
unsigned char * pucRandom,
size_t xRandomLength )
{
/* Must cast from void pointer to conform to mbed TLS API. */
SSLContext_t * pxCtx = ( SSLContext_t * ) pvCtx;
CK_RV xResult;
xResult = pxCtx->pxP11FunctionList->C_GenerateRandom( pxCtx->xP11Session, pucRandom, xRandomLength );
if( xResult != CKR_OK )
{
LogError( ( "Failed to generate random bytes from the PKCS #11 module." ) );
}
return (int) xResult;
}
static void SSL_contextInit( SSLContext_t * pSslContext )
{
configASSERT( pSslContext != NULL );
mbedtls_ssl_config_init( &( pSslContext->config ) );
mbedtls_x509_crt_init( &( pSslContext->rootCa ) );
mbedtls_pk_init( &( pSslContext->privKey ) );
// mbedtls_x509_crt_init( &( pSslContext->clientCert ) );
mbedtls_ssl_init( &( pSslContext->context ) );
}