in lib/FreeRTOS/network_transport/freertos_plus_tcp/using_mbedtls_pkcs11/using_mbedtls_pkcs11.c [220:447]
static TlsTransportStatus_t tlsSetup( NetworkContext_t * pNetworkContext,
const char * pHostName,
const NetworkCredentials_t * pNetworkCredentials )
{
TlsTransportStatus_t returnStatus = TLS_TRANSPORT_SUCCESS;
int32_t mbedtlsError = 0;
CK_RV xResult = CKR_OK;
configASSERT( pNetworkContext != NULL );
configASSERT( pHostName != NULL );
configASSERT( pNetworkCredentials != NULL );
configASSERT( pNetworkCredentials->pRootCa != NULL );
/* Initialize the mbed TLS context structures. */
sslContextInit( &( pNetworkContext->sslContext ) );
mbedtlsError = mbedtls_ssl_config_defaults( &( pNetworkContext->sslContext.config ),
MBEDTLS_SSL_IS_CLIENT,
MBEDTLS_SSL_TRANSPORT_STREAM,
MBEDTLS_SSL_PRESET_DEFAULT );
if( mbedtlsError != 0 )
{
LogError( ( "Failed to set default SSL configuration: mbedTLSError= %s : %s.",
mbedtlsHighLevelCodeOrDefault( mbedtlsError ),
mbedtlsLowLevelCodeOrDefault( mbedtlsError ) ) );
/* Per mbed TLS docs, mbedtls_ssl_config_defaults only fails on memory allocation. */
returnStatus = TLS_TRANSPORT_INSUFFICIENT_MEMORY;
}
if( returnStatus == TLS_TRANSPORT_SUCCESS )
{
/* Set up the certificate security profile, starting from the default value. */
pNetworkContext->sslContext.certProfile = mbedtls_x509_crt_profile_default;
/* test.mosquitto.org only provides a 1024-bit RSA certificate, which is
* not acceptable by the default mbed TLS certificate security profile.
* For the purposes of this demo, allow the use of 1024-bit RSA certificates.
* This block should be removed otherwise. */
if( strncmp( pHostName, "test.mosquitto.org", strlen( pHostName ) ) == 0 )
{
pNetworkContext->sslContext.certProfile.rsa_min_bitlen = 1024;
}
/* Set SSL authmode and the RNG context. */
mbedtls_ssl_conf_authmode( &( pNetworkContext->sslContext.config ),
MBEDTLS_SSL_VERIFY_REQUIRED );
mbedtls_ssl_conf_rng( &( pNetworkContext->sslContext.config ),
generateRandomBytes,
&pNetworkContext->sslContext );
mbedtls_ssl_conf_cert_profile( &( pNetworkContext->sslContext.config ),
&( pNetworkContext->sslContext.certProfile ) );
/* Parse the server root CA certificate into the SSL context. */
mbedtlsError = mbedtls_x509_crt_parse( &( pNetworkContext->sslContext.rootCa ),
pNetworkCredentials->pRootCa,
pNetworkCredentials->rootCaSize );
if( mbedtlsError != 0 )
{
LogError( ( "Failed to parse server root CA certificate: mbedTLSError= %s : %s.",
mbedtlsHighLevelCodeOrDefault( mbedtlsError ),
mbedtlsLowLevelCodeOrDefault( mbedtlsError ) ) );
returnStatus = TLS_TRANSPORT_INVALID_CREDENTIALS;
}
else
{
mbedtls_ssl_conf_ca_chain( &( pNetworkContext->sslContext.config ),
&( pNetworkContext->sslContext.rootCa ),
NULL );
}
}
if( returnStatus == TLS_TRANSPORT_SUCCESS )
{
/* Setup the client private key. */
xResult = initializeClientKeys( &( pNetworkContext->sslContext ) );
if( xResult != CKR_OK )
{
LogError( ( "Failed to setup key handling by PKCS #11." ) );
returnStatus = TLS_TRANSPORT_INVALID_CREDENTIALS;
}
else
{
/* Setup the client certificate. */
xResult = readCertificateIntoContext( &( pNetworkContext->sslContext ),
pkcs11configLABEL_DEVICE_CERTIFICATE_FOR_TLS,
CKO_CERTIFICATE,
&( pNetworkContext->sslContext.clientCert ) );
if( xResult != CKR_OK )
{
LogError( ( "Failed to get certificate from PKCS #11 module." ) );
returnStatus = TLS_TRANSPORT_INVALID_CREDENTIALS;
}
else
{
( void ) mbedtls_ssl_conf_own_cert( &( pNetworkContext->sslContext.config ),
&( pNetworkContext->sslContext.clientCert ),
&( pNetworkContext->sslContext.privKey ) );
}
}
}
if( ( returnStatus == TLS_TRANSPORT_SUCCESS ) && ( pNetworkCredentials->pAlpnProtos != NULL ) )
{
/* Include an application protocol list in the TLS ClientHello
* message. */
mbedtlsError = mbedtls_ssl_conf_alpn_protocols( &( pNetworkContext->sslContext.config ),
pNetworkCredentials->pAlpnProtos );
if( mbedtlsError != 0 )
{
LogError( ( "Failed to configure ALPN protocol in mbed TLS: mbedTLSError= %s : %s.",
mbedtlsHighLevelCodeOrDefault( mbedtlsError ),
mbedtlsLowLevelCodeOrDefault( mbedtlsError ) ) );
returnStatus = TLS_TRANSPORT_INTERNAL_ERROR;
}
}
if( returnStatus == TLS_TRANSPORT_SUCCESS )
{
/* Initialize the mbed TLS secured connection context. */
mbedtlsError = mbedtls_ssl_setup( &( pNetworkContext->sslContext.context ),
&( pNetworkContext->sslContext.config ) );
if( mbedtlsError != 0 )
{
LogError( ( "Failed to set up mbed TLS SSL context: mbedTLSError= %s : %s.",
mbedtlsHighLevelCodeOrDefault( mbedtlsError ),
mbedtlsLowLevelCodeOrDefault( mbedtlsError ) ) );
returnStatus = TLS_TRANSPORT_INTERNAL_ERROR;
}
else
{
/* Set the underlying IO for the TLS connection. */
/* MISRA Rule 11.2 flags the following line for casting the second
* parameter to void *. This rule is suppressed because
* #mbedtls_ssl_set_bio requires the second parameter as void *.
*/
/* coverity[misra_c_2012_rule_11_2_violation] */
mbedtls_ssl_set_bio( &( pNetworkContext->sslContext.context ),
( void * ) pNetworkContext->tcpSocket,
mbedtls_platform_send,
mbedtls_platform_recv,
NULL );
}
}
if( returnStatus == TLS_TRANSPORT_SUCCESS )
{
/* Enable SNI if requested. */
if( pNetworkCredentials->disableSni == pdFALSE )
{
mbedtlsError = mbedtls_ssl_set_hostname( &( pNetworkContext->sslContext.context ),
pHostName );
if( mbedtlsError != 0 )
{
LogError( ( "Failed to set server name: mbedTLSError= %s : %s.",
mbedtlsHighLevelCodeOrDefault( mbedtlsError ),
mbedtlsLowLevelCodeOrDefault( mbedtlsError ) ) );
returnStatus = 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( &( pNetworkContext->sslContext.config ), MBEDTLS_SSL_MAX_FRAG_LEN_4096 );
if( mbedtlsError != 0 )
{
LogError( ( "Failed to maximum fragment length extension: mbedTLSError= %s : %s.",
mbedtlsHighLevelCodeOrDefault( mbedtlsError ),
mbedtlsLowLevelCodeOrDefault( mbedtlsError ) ) );
returnStatus = TLS_TRANSPORT_INTERNAL_ERROR;
}
}
#endif /* ifdef MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
if( returnStatus == TLS_TRANSPORT_SUCCESS )
{
/* Perform the TLS handshake. */
do
{
mbedtlsError = mbedtls_ssl_handshake( &( pNetworkContext->sslContext.context ) );
} while( ( mbedtlsError == MBEDTLS_ERR_SSL_WANT_READ ) ||
( mbedtlsError == MBEDTLS_ERR_SSL_WANT_WRITE ) );
if( mbedtlsError != 0 )
{
LogError( ( "Failed to perform TLS handshake: mbedTLSError= %s : %s.",
mbedtlsHighLevelCodeOrDefault( mbedtlsError ),
mbedtlsLowLevelCodeOrDefault( mbedtlsError ) ) );
returnStatus = TLS_TRANSPORT_HANDSHAKE_FAILED;
}
}
if( returnStatus != TLS_TRANSPORT_SUCCESS )
{
sslContextFree( &( pNetworkContext->sslContext ) );
}
else
{
LogInfo( ( "(Network connection %p) TLS handshake successful.",
pNetworkContext ) );
}
return returnStatus;
}