mirror of
https://github.com/FreeRTOS/FreeRTOS.git
synced 2025-06-21 07:41:15 +08:00
Fix MISRA warnings for platform code used by MQTT demos (#337)
In addition to fixing MISRA warnings, code is updated to have complexity <= 8. Also, this adds changes from PR #313, which allows the support of simultaneous connections in the mbedTLS transport wrapper. Co-authored-by: Muneeb Ahmed <54290492+muneebahmed10@users.noreply.github.com>
This commit is contained in:

committed by
GitHub

parent
02aafc3a46
commit
5f0bf944cb
@ -190,22 +190,12 @@
|
|||||||
*/
|
*/
|
||||||
#define AWS_IOT_MQTT_ALPN "\x0ex-amzn-mqtt-ca"
|
#define AWS_IOT_MQTT_ALPN "\x0ex-amzn-mqtt-ca"
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Length of ALPN protocol name.
|
|
||||||
*/
|
|
||||||
#define AWS_IOT_MQTT_ALPN_LENGTH ( ( uint16_t ) ( sizeof( AWS_IOT_MQTT_ALPN ) - 1 ) )
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This is the ALPN (Application-Layer Protocol Negotiation) string
|
* @brief This is the ALPN (Application-Layer Protocol Negotiation) string
|
||||||
* required by AWS IoT for password-based authentication using TCP port 443.
|
* required by AWS IoT for password-based authentication using TCP port 443.
|
||||||
*/
|
*/
|
||||||
#define AWS_IOT_CUSTOM_AUTH_ALPN "\x04mqtt"
|
#define AWS_IOT_CUSTOM_AUTH_ALPN "\x04mqtt"
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Length of password ALPN.
|
|
||||||
*/
|
|
||||||
#define AWS_IOT_CUSTOM_AUTH_ALPN_LENGTH ( ( uint16_t ) ( sizeof( AWS_IOT_CUSTOM_AUTH_ALPN ) - 1 ) )
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provide default values for undefined configuration settings.
|
* Provide default values for undefined configuration settings.
|
||||||
*/
|
*/
|
||||||
@ -567,6 +557,11 @@ static TlsTransportStatus_t prvConnectToServerWithBackoffRetries( NetworkCredent
|
|||||||
RetryUtilsStatus_t xRetryUtilsStatus = RetryUtilsSuccess;
|
RetryUtilsStatus_t xRetryUtilsStatus = RetryUtilsSuccess;
|
||||||
RetryUtilsParams_t xReconnectParams;
|
RetryUtilsParams_t xReconnectParams;
|
||||||
|
|
||||||
|
/* ALPN protocols must be a NULL-terminated list of strings. Therefore,
|
||||||
|
* the first entry will contain the actual ALPN protocol string while the
|
||||||
|
* second entry must remain NULL. */
|
||||||
|
char * pcAlpnProtocols[] = { NULL, NULL };
|
||||||
|
|
||||||
/* Set the credentials for establishing a TLS connection. */
|
/* Set the credentials for establishing a TLS connection. */
|
||||||
pxNetworkCredentials->pRootCa = ( const unsigned char * ) democonfigROOT_CA_PEM;
|
pxNetworkCredentials->pRootCa = ( const unsigned char * ) democonfigROOT_CA_PEM;
|
||||||
pxNetworkCredentials->rootCaSize = sizeof( democonfigROOT_CA_PEM );
|
pxNetworkCredentials->rootCaSize = sizeof( democonfigROOT_CA_PEM );
|
||||||
@ -580,11 +575,12 @@ static TlsTransportStatus_t prvConnectToServerWithBackoffRetries( NetworkCredent
|
|||||||
pxNetworkCredentials->disableSni = pdFALSE;
|
pxNetworkCredentials->disableSni = pdFALSE;
|
||||||
/* The ALPN string changes depending on whether username/password authentication is used. */
|
/* The ALPN string changes depending on whether username/password authentication is used. */
|
||||||
#ifdef democonfigCLIENT_USERNAME
|
#ifdef democonfigCLIENT_USERNAME
|
||||||
pxNetworkCredentials->pAlpnProtos = AWS_IOT_CUSTOM_AUTH_ALPN;
|
pcAlpnProtocols[ 0 ] = AWS_IOT_CUSTOM_AUTH_ALPN;
|
||||||
#else
|
#else
|
||||||
pxNetworkCredentials->pAlpnProtos = AWS_IOT_MQTT_ALPN;
|
pcAlpnProtocols[ 0 ] = AWS_IOT_MQTT_ALPN;
|
||||||
#endif
|
#endif
|
||||||
#else
|
pxNetworkCredentials->pAlpnProtos = pcAlpnProtocols;
|
||||||
|
#else /* ifdef democonfigUSE_AWS_IOT_CORE_BROKER */
|
||||||
|
|
||||||
/* When using a local Mosquitto server setup, SNI needs to be disabled for
|
/* When using a local Mosquitto server setup, SNI needs to be disabled for
|
||||||
* an MQTT broker that only has an IP address but no hostname. However,
|
* an MQTT broker that only has an IP address but no hostname. However,
|
||||||
@ -686,7 +682,7 @@ static void prvCreateMQTTConnectionWithBroker( MQTTContext_t * pxMQTTContext,
|
|||||||
/* Password for authentication is not used. */
|
/* Password for authentication is not used. */
|
||||||
xConnectInfo.pPassword = NULL;
|
xConnectInfo.pPassword = NULL;
|
||||||
xConnectInfo.passwordLength = 0U;
|
xConnectInfo.passwordLength = 0U;
|
||||||
#endif /* ifdef democonfigCLIENT_USERNAME */
|
#endif
|
||||||
#else /* ifdef democonfigUSE_AWS_IOT_CORE_BROKER */
|
#else /* ifdef democonfigUSE_AWS_IOT_CORE_BROKER */
|
||||||
#ifdef democonfigCLIENT_USERNAME
|
#ifdef democonfigCLIENT_USERNAME
|
||||||
xConnectInfo.pUserName = democonfigCLIENT_USERNAME;
|
xConnectInfo.pUserName = democonfigCLIENT_USERNAME;
|
||||||
|
@ -18,9 +18,6 @@
|
|||||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*
|
|
||||||
* http://aws.amazon.com/freertos
|
|
||||||
* http://www.FreeRTOS.org
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -205,19 +202,21 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
const char * mbedtls_strerror_highlevel( int errnum )
|
const char * mbedtls_strerror_highlevel( int32_t errnum )
|
||||||
{
|
{
|
||||||
const char * rc = NULL;
|
const char * rc = NULL;
|
||||||
int use_ret;
|
uint32_t use_ret = 0;
|
||||||
|
|
||||||
if( errnum < 0 )
|
if( errnum < 0 )
|
||||||
{
|
{
|
||||||
errnum = -errnum;
|
use_ret = ( uint32_t ) -errnum;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
use_ret = ( uint32_t ) errnum;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( errnum & 0xFF80 )
|
use_ret &= 0xFF80;
|
||||||
{
|
|
||||||
use_ret = errnum & 0xFF80;
|
|
||||||
|
|
||||||
/* High level error codes */
|
/* High level error codes */
|
||||||
switch( use_ret )
|
switch( use_ret )
|
||||||
@ -851,30 +850,31 @@ const char * mbedtls_strerror_highlevel( int errnum )
|
|||||||
rc = "X509 - A fatal error occured, eg the chain is too long or the vrfy callback failed";
|
rc = "X509 - A fatal error occured, eg the chain is too long or the vrfy callback failed";
|
||||||
break;
|
break;
|
||||||
#endif /* MBEDTLS_X509_USE_C || MBEDTLS_X509_CREATE_C */
|
#endif /* MBEDTLS_X509_USE_C || MBEDTLS_X509_CREATE_C */
|
||||||
/* END generated code */
|
|
||||||
}
|
default:
|
||||||
|
rc = NULL;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char * mbedtls_strerror_lowlevel( int errnum )
|
const char * mbedtls_strerror_lowlevel( int32_t errnum )
|
||||||
{
|
{
|
||||||
const char * rc = NULL;
|
const char * rc = NULL;
|
||||||
int use_ret;
|
uint32_t use_ret = 0;
|
||||||
|
|
||||||
if( errnum < 0 )
|
if( errnum < 0 )
|
||||||
{
|
{
|
||||||
errnum = -errnum;
|
use_ret = ( uint32_t ) -errnum;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
use_ret = errnum & ~0xFF80;
|
|
||||||
|
|
||||||
if( use_ret == 0 )
|
|
||||||
{
|
{
|
||||||
return NULL;
|
use_ret = ( uint32_t ) errnum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
use_ret &= 0xFF80;
|
||||||
|
|
||||||
/* Low level error codes */
|
/* Low level error codes */
|
||||||
/* */
|
/* */
|
||||||
switch( use_ret )
|
switch( use_ret )
|
||||||
@ -1330,6 +1330,10 @@ const char * mbedtls_strerror_lowlevel( int errnum )
|
|||||||
rc = "XTEA - XTEA hardware accelerator failed";
|
rc = "XTEA - XTEA hardware accelerator failed";
|
||||||
break;
|
break;
|
||||||
#endif /* MBEDTLS_XTEA_C */
|
#endif /* MBEDTLS_XTEA_C */
|
||||||
|
|
||||||
|
default:
|
||||||
|
rc = NULL;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
|
@ -18,7 +18,6 @@
|
|||||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -26,10 +25,14 @@
|
|||||||
* @brief Stringification utilities for high-level and low-level codes of mbed TLS.
|
* @brief Stringification utilities for high-level and low-level codes of mbed TLS.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef MBEDTLS_ERROR_H_
|
||||||
|
#define MBEDTLS_ERROR_H_
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Translate an mbed TLS high level code into its string representation.
|
* @brief Translate an mbed TLS high level code into its string representation.
|
||||||
@ -40,7 +43,7 @@
|
|||||||
*
|
*
|
||||||
* @warning The string returned by this function must never be modified.
|
* @warning The string returned by this function must never be modified.
|
||||||
*/
|
*/
|
||||||
const char * mbedtls_strerror_highlevel( int errnum );
|
const char * mbedtls_strerror_highlevel( int32_t errnum );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Translate an mbed TLS low level code into its string representation,
|
* @brief Translate an mbed TLS low level code into its string representation,
|
||||||
@ -51,8 +54,10 @@ const char * mbedtls_strerror_highlevel( int errnum );
|
|||||||
*
|
*
|
||||||
* @warning The string returned by this function must never be modified.
|
* @warning The string returned by this function must never be modified.
|
||||||
*/
|
*/
|
||||||
const char * mbedtls_strerror_lowlevel( int errnum );
|
const char * mbedtls_strerror_lowlevel( int32_t errnum );
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif /* ifndef MBEDTLS_ERROR_H_ */
|
||||||
|
@ -54,7 +54,7 @@ void * mbedtls_platform_calloc( size_t nmemb,
|
|||||||
if( totalSize > 0 )
|
if( totalSize > 0 )
|
||||||
{
|
{
|
||||||
/* Overflow check. */
|
/* Overflow check. */
|
||||||
if( totalSize / size == nmemb )
|
if( ( totalSize / size ) == nmemb )
|
||||||
{
|
{
|
||||||
pBuffer = pvPortMalloc( totalSize );
|
pBuffer = pvPortMalloc( totalSize );
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
|
|
||||||
#include "retry_utils.h"
|
#include "retry_utils.h"
|
||||||
|
|
||||||
#define _MILLISECONDS_PER_SECOND ( 1000U ) /**< @brief Milliseconds per second. */
|
#define MILLISECONDS_PER_SECOND ( 1000U ) /**< @brief Milliseconds per second. */
|
||||||
|
|
||||||
extern UBaseType_t uxRand( void );
|
extern UBaseType_t uxRand( void );
|
||||||
|
|
||||||
@ -42,17 +42,17 @@ extern UBaseType_t uxRand( void );
|
|||||||
RetryUtilsStatus_t RetryUtils_BackoffAndSleep( RetryUtilsParams_t * pRetryParams )
|
RetryUtilsStatus_t RetryUtils_BackoffAndSleep( RetryUtilsParams_t * pRetryParams )
|
||||||
{
|
{
|
||||||
RetryUtilsStatus_t status = RetryUtilsRetriesExhausted;
|
RetryUtilsStatus_t status = RetryUtilsRetriesExhausted;
|
||||||
int32_t backOffDelayMs = 0;
|
uint32_t backOffDelayMs = 0;
|
||||||
|
|
||||||
/* If pRetryParams->maxRetryAttempts is set to 0, try forever. */
|
/* If pRetryParams->maxRetryAttempts is set to 0, try forever. */
|
||||||
if( ( pRetryParams->attemptsDone < pRetryParams->maxRetryAttempts ) ||
|
if( ( pRetryParams->attemptsDone < pRetryParams->maxRetryAttempts ) ||
|
||||||
( 0 == pRetryParams->maxRetryAttempts ) )
|
( 0U == pRetryParams->maxRetryAttempts ) )
|
||||||
{
|
{
|
||||||
/* Choose a random value for back-off time between 0 and the max jitter value. */
|
/* Choose a random value for back-off time between 0 and the max jitter value. */
|
||||||
backOffDelayMs = uxRand() % pRetryParams->nextJitterMax;
|
backOffDelayMs = uxRand() % pRetryParams->nextJitterMax;
|
||||||
|
|
||||||
/* Wait for backoff time to expire for the next retry. */
|
/* Wait for backoff time to expire for the next retry. */
|
||||||
vTaskDelay( pdMS_TO_TICKS( backOffDelayMs * _MILLISECONDS_PER_SECOND ) );
|
vTaskDelay( pdMS_TO_TICKS( backOffDelayMs * MILLISECONDS_PER_SECOND ) );
|
||||||
|
|
||||||
/* Increment backoff counts. */
|
/* Increment backoff counts. */
|
||||||
pRetryParams->attemptsDone++;
|
pRetryParams->attemptsDone++;
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
/* FreeRTOS+TCP includes. */
|
/* FreeRTOS+TCP includes. */
|
||||||
#include "FreeRTOS_IP.h"
|
#include "FreeRTOS_IP.h"
|
||||||
#include "FreeRTOS_Sockets.h"
|
#include "FreeRTOS_Sockets.h"
|
||||||
|
#include "FreeRTOS_DNS.h"
|
||||||
|
|
||||||
/**************************************************/
|
/**************************************************/
|
||||||
/******* DO NOT CHANGE the following order ********/
|
/******* DO NOT CHANGE the following order ********/
|
||||||
|
@ -76,6 +76,8 @@ typedef struct SSLContext
|
|||||||
mbedtls_x509_crt rootCa; /**< @brief Root CA certificate context. */
|
mbedtls_x509_crt rootCa; /**< @brief Root CA certificate context. */
|
||||||
mbedtls_x509_crt clientCert; /**< @brief Client certificate context. */
|
mbedtls_x509_crt clientCert; /**< @brief Client certificate context. */
|
||||||
mbedtls_pk_context privKey; /**< @brief Client private key context. */
|
mbedtls_pk_context privKey; /**< @brief Client private key context. */
|
||||||
|
mbedtls_entropy_context entropyContext; /**< @brief Entropy context for random number generation. */
|
||||||
|
mbedtls_ctr_drbg_context ctrDrgbContext; /**< @brief CTR DRBG context for random number generation. */
|
||||||
} SSLContext_t;
|
} SSLContext_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -94,31 +96,26 @@ struct NetworkContext
|
|||||||
typedef struct NetworkCredentials
|
typedef struct NetworkCredentials
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @brief Set this to a non-NULL value to use ALPN.
|
* @brief To use ALPN, set this to a NULL-terminated list of supported
|
||||||
*
|
* protocols in decreasing order of preference.
|
||||||
* This string must be NULL-terminated.
|
|
||||||
*
|
*
|
||||||
* See [this link]
|
* See [this link]
|
||||||
* (https://aws.amazon.com/blogs/iot/mqtt-with-tls-client-authentication-on-port-443-why-it-is-useful-and-how-it-works/)
|
* (https://aws.amazon.com/blogs/iot/mqtt-with-tls-client-authentication-on-port-443-why-it-is-useful-and-how-it-works/)
|
||||||
* for more information.
|
* for more information.
|
||||||
*/
|
*/
|
||||||
const char * pAlpnProtos;
|
const char ** pAlpnProtos;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Disable server name indication (SNI) for a TLS session.
|
* @brief Disable server name indication (SNI) for a TLS session.
|
||||||
*/
|
*/
|
||||||
BaseType_t disableSni;
|
BaseType_t disableSni;
|
||||||
|
|
||||||
const unsigned char * pRootCa; /**< @brief String representing a trusted server root certificate. */
|
const uint8_t * pRootCa; /**< @brief String representing a trusted server root certificate. */
|
||||||
size_t rootCaSize; /**< @brief Size associated with #IotNetworkCredentials.pRootCa. */
|
size_t rootCaSize; /**< @brief Size associated with #NetworkCredentials.pRootCa. */
|
||||||
const unsigned char * pClientCert; /**< @brief String representing the client certificate. */
|
const uint8_t * pClientCert; /**< @brief String representing the client certificate. */
|
||||||
size_t clientCertSize; /**< @brief Size associated with #IotNetworkCredentials.pClientCert. */
|
size_t clientCertSize; /**< @brief Size associated with #NetworkCredentials.pClientCert. */
|
||||||
const unsigned char * pPrivateKey; /**< @brief String representing the client certificate's private key. */
|
const uint8_t * pPrivateKey; /**< @brief String representing the client certificate's private key. */
|
||||||
size_t privateKeySize; /**< @brief Size associated with #IotNetworkCredentials.pPrivateKey. */
|
size_t privateKeySize; /**< @brief Size associated with #NetworkCredentials.pPrivateKey. */
|
||||||
const unsigned char * pUserName; /**< @brief String representing the username for MQTT. */
|
|
||||||
size_t userNameSize; /**< @brief Size associated with #IotNetworkCredentials.pUserName. */
|
|
||||||
const unsigned char * pPassword; /**< @brief String representing the password for MQTT. */
|
|
||||||
size_t passwordSize; /**< @brief Size associated with #IotNetworkCredentials.pPassword. */
|
|
||||||
} NetworkCredentials_t;
|
} NetworkCredentials_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -109,15 +109,14 @@ struct NetworkContext
|
|||||||
typedef struct NetworkCredentials
|
typedef struct NetworkCredentials
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @brief Set this to a non-NULL value to use ALPN.
|
* @brief To use ALPN, set this to a NULL-terminated list of supported
|
||||||
*
|
* protocols in decreasing order of preference.
|
||||||
* This string must be NULL-terminated.
|
|
||||||
*
|
*
|
||||||
* See [this link]
|
* See [this link]
|
||||||
* (https://aws.amazon.com/blogs/iot/mqtt-with-tls-client-authentication-on-port-443-why-it-is-useful-and-how-it-works/)
|
* (https://aws.amazon.com/blogs/iot/mqtt-with-tls-client-authentication-on-port-443-why-it-is-useful-and-how-it-works/)
|
||||||
* for more information.
|
* for more information.
|
||||||
*/
|
*/
|
||||||
const char * pAlpnProtos;
|
const char ** pAlpnProtos;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Disable server name indication (SNI) for a TLS session.
|
* @brief Disable server name indication (SNI) for a TLS session.
|
||||||
@ -125,11 +124,11 @@ typedef struct NetworkCredentials
|
|||||||
BaseType_t disableSni;
|
BaseType_t disableSni;
|
||||||
|
|
||||||
const unsigned char * pRootCa; /**< @brief String representing a trusted server root certificate. */
|
const unsigned char * pRootCa; /**< @brief String representing a trusted server root certificate. */
|
||||||
size_t rootCaSize; /**< @brief Size associated with #IotNetworkCredentials.pRootCa. */
|
size_t rootCaSize; /**< @brief Size associated with #NetworkCredentials.pRootCa. */
|
||||||
const unsigned char * pUserName; /**< @brief String representing the username for MQTT. */
|
const unsigned char * pUserName; /**< @brief String representing the username for MQTT. */
|
||||||
size_t userNameSize; /**< @brief Size associated with #IotNetworkCredentials.pUserName. */
|
size_t userNameSize; /**< @brief Size associated with #NetworkCredentials.pUserName. */
|
||||||
const unsigned char * pPassword; /**< @brief String representing the password for MQTT. */
|
const unsigned char * pPassword; /**< @brief String representing the password for MQTT. */
|
||||||
size_t passwordSize; /**< @brief Size associated with #IotNetworkCredentials.pPassword. */
|
size_t passwordSize; /**< @brief Size associated with #NetworkCredentials.pPassword. */
|
||||||
} NetworkCredentials_t;
|
} NetworkCredentials_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -70,11 +70,11 @@ BaseType_t Sockets_Connect( Socket_t * pTcpSocket,
|
|||||||
/* Connection parameters. */
|
/* Connection parameters. */
|
||||||
serverAddress.sin_family = FREERTOS_AF_INET;
|
serverAddress.sin_family = FREERTOS_AF_INET;
|
||||||
serverAddress.sin_port = FreeRTOS_htons( port );
|
serverAddress.sin_port = FreeRTOS_htons( port );
|
||||||
serverAddress.sin_addr = FreeRTOS_gethostbyname( pHostName );
|
serverAddress.sin_addr = ( uint32_t ) FreeRTOS_gethostbyname( pHostName );
|
||||||
serverAddress.sin_len = ( uint8_t ) sizeof( serverAddress );
|
serverAddress.sin_len = ( uint8_t ) sizeof( serverAddress );
|
||||||
|
|
||||||
/* Check for errors from DNS lookup. */
|
/* Check for errors from DNS lookup. */
|
||||||
if( serverAddress.sin_addr == 0 )
|
if( serverAddress.sin_addr == 0U )
|
||||||
{
|
{
|
||||||
LogError( ( "Failed to connect to server: DNS resolution failed: Hostname=%s.",
|
LogError( ( "Failed to connect to server: DNS resolution failed: Hostname=%s.",
|
||||||
pHostName ) );
|
pHostName ) );
|
||||||
@ -124,7 +124,7 @@ BaseType_t Sockets_Connect( Socket_t * pTcpSocket,
|
|||||||
{
|
{
|
||||||
if( tcpSocket != FREERTOS_INVALID_SOCKET )
|
if( tcpSocket != FREERTOS_INVALID_SOCKET )
|
||||||
{
|
{
|
||||||
FreeRTOS_closesocket( tcpSocket );
|
( void ) FreeRTOS_closesocket( tcpSocket );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -76,18 +76,6 @@ static const char * pNoLowLevelMbedTlsCodeStr = "<No-Low-Level-Code>";
|
|||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief mbed TLS entropy context for generation of random numbers.
|
|
||||||
*/
|
|
||||||
static mbedtls_entropy_context entropyContext;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief mbed TLS CTR DRBG context for generation of random numbers.
|
|
||||||
*/
|
|
||||||
static mbedtls_ctr_drbg_context ctrDrgbContext;
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initialize the mbed TLS structures in a network connection.
|
* @brief Initialize the mbed TLS structures in a network connection.
|
||||||
*
|
*
|
||||||
@ -103,25 +91,111 @@ static void sslContextInit( SSLContext_t * pSslContext );
|
|||||||
static void sslContextFree( SSLContext_t * pSslContext );
|
static void sslContextFree( SSLContext_t * pSslContext );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set up TLS on a TCP connection.
|
* @brief Add X509 certificate to the trusted list of root certificates.
|
||||||
|
*
|
||||||
|
* OpenSSL does not provide a single function for reading and loading certificates
|
||||||
|
* from files into stores, so the file API must be called. Start with the
|
||||||
|
* root certificate.
|
||||||
|
*
|
||||||
|
* @param[out] pSslContext SSL context to which the trusted server root CA is to be added.
|
||||||
|
* @param[in] pRootCa PEM-encoded string of the trusted server root CA.
|
||||||
|
* @param[in] rootCaSize Size of the trusted server root CA.
|
||||||
|
*
|
||||||
|
* @return 0 on success; otherwise, failure;
|
||||||
|
*/
|
||||||
|
static int32_t setRootCa( SSLContext_t * pSslContext,
|
||||||
|
const uint8_t * pRootCa,
|
||||||
|
size_t rootCaSize );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set X509 certificate as client certificate for the server to authenticate.
|
||||||
|
*
|
||||||
|
* @param[out] pSslContext SSL context to which the client certificate is to be set.
|
||||||
|
* @param[in] pClientCert PEM-encoded string of the client certificate.
|
||||||
|
* @param[in] clientCertSize Size of the client certificate.
|
||||||
|
*
|
||||||
|
* @return 0 on success; otherwise, failure;
|
||||||
|
*/
|
||||||
|
static int32_t setClientCertificate( SSLContext_t * pSslContext,
|
||||||
|
const uint8_t * pClientCert,
|
||||||
|
size_t clientCertSize );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set private key for the client's certificate.
|
||||||
|
*
|
||||||
|
* @param[out] pSslContext SSL context to which the private key is to be set.
|
||||||
|
* @param[in] pPrivateKey PEM-encoded string of the client private key.
|
||||||
|
* @param[in] privateKeySize Size of the client private key.
|
||||||
|
*
|
||||||
|
* @return 0 on success; otherwise, failure;
|
||||||
|
*/
|
||||||
|
static int32_t setPrivateKey( SSLContext_t * pSslContext,
|
||||||
|
const uint8_t * pPrivateKey,
|
||||||
|
size_t privateKeySize );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Passes TLS credentials to the OpenSSL library.
|
||||||
|
*
|
||||||
|
* Provides the root CA certificate, client certificate, and private key to the
|
||||||
|
* OpenSSL library. If the client certificate or private key is not NULL, mutual
|
||||||
|
* authentication is used when performing the TLS handshake.
|
||||||
|
*
|
||||||
|
* @param[out] pSslContext SSL context to which the credentials are to be imported.
|
||||||
|
* @param[in] pNetworkCredentials TLS credentials to be imported.
|
||||||
|
*
|
||||||
|
* @return 0 on success; otherwise, failure;
|
||||||
|
*/
|
||||||
|
static int32_t setCredentials( SSLContext_t * pSslContext,
|
||||||
|
const NetworkCredentials_t * pNetworkCredentials );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set optional configurations for the TLS connection.
|
||||||
|
*
|
||||||
|
* This function is used to set SNI and ALPN protocols.
|
||||||
|
*
|
||||||
|
* @param[in] pSslContext SSL context to which the optional configurations are to be set.
|
||||||
|
* @param[in] pHostName Remote host name, used for server name indication.
|
||||||
|
* @param[in] pNetworkCredentials TLS setup parameters.
|
||||||
|
*/
|
||||||
|
static void setOptionalConfigurations( SSLContext_t * pSslContext,
|
||||||
|
const char * pHostName,
|
||||||
|
const NetworkCredentials_t * pNetworkCredentials );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Setup TLS by initializing contexts and setting configurations.
|
||||||
*
|
*
|
||||||
* @param[in] pNetworkContext Network context.
|
* @param[in] pNetworkContext Network context.
|
||||||
* @param[in] pHostName Remote host name, used for server name indication.
|
* @param[in] pHostName Remote host name, used for server name indication.
|
||||||
* @param[in] pNetworkCredentials TLS setup parameters.
|
* @param[in] pNetworkCredentials TLS setup parameters.
|
||||||
*
|
*
|
||||||
* @return #TLS_TRANSPORT_SUCCESS, #TLS_TRANSPORT_INSUFFICIENT_MEMORY, #TLS_TRANSPORT_INVALID_CREDENTIALS,
|
* @return #TLS_TRANSPORT_SUCCESS, #TLS_TRANSPORT_INSUFFICIENT_MEMORY, #TLS_TRANSPORT_INVALID_CREDENTIALS,
|
||||||
* #TLS_TRANSPORT_HANDSHAKE_FAILED, or #TLS_TRANSPORT_INTERNAL_ERROR.
|
* or #TLS_TRANSPORT_INTERNAL_ERROR.
|
||||||
*/
|
*/
|
||||||
static TlsTransportStatus_t tlsSetup( NetworkContext_t * pNetworkContext,
|
static TlsTransportStatus_t tlsSetup( NetworkContext_t * pNetworkContext,
|
||||||
const char * pHostName,
|
const char * pHostName,
|
||||||
const NetworkCredentials_t * pNetworkCredentials );
|
const NetworkCredentials_t * pNetworkCredentials );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Perform the TLS handshake on a TCP connection.
|
||||||
|
*
|
||||||
|
* @param[in] pNetworkContext Network context.
|
||||||
|
* @param[in] pNetworkCredentials TLS setup parameters.
|
||||||
|
*
|
||||||
|
* @return #TLS_TRANSPORT_SUCCESS, #TLS_TRANSPORT_HANDSHAKE_FAILED, or #TLS_TRANSPORT_INTERNAL_ERROR.
|
||||||
|
*/
|
||||||
|
static TlsTransportStatus_t tlsHandshake( NetworkContext_t * pNetworkContext,
|
||||||
|
const NetworkCredentials_t * pNetworkCredentials );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initialize mbedTLS.
|
* @brief Initialize mbedTLS.
|
||||||
*
|
*
|
||||||
|
* @param[out] entropyContext mbed TLS entropy context for generation of random numbers.
|
||||||
|
* @param[out] ctrDrgbContext mbed TLS CTR DRBG context for generation of random numbers.
|
||||||
|
*
|
||||||
* @return #TLS_TRANSPORT_SUCCESS, or #TLS_TRANSPORT_INTERNAL_ERROR.
|
* @return #TLS_TRANSPORT_SUCCESS, or #TLS_TRANSPORT_INTERNAL_ERROR.
|
||||||
*/
|
*/
|
||||||
static TlsTransportStatus_t initMbedtls( void );
|
static TlsTransportStatus_t initMbedtls( mbedtls_entropy_context * pEntropyContext,
|
||||||
|
mbedtls_ctr_drbg_context * pCtrDrgbContext );
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
@ -145,9 +219,190 @@ static void sslContextFree( SSLContext_t * pSslContext )
|
|||||||
mbedtls_x509_crt_free( &( pSslContext->rootCa ) );
|
mbedtls_x509_crt_free( &( pSslContext->rootCa ) );
|
||||||
mbedtls_x509_crt_free( &( pSslContext->clientCert ) );
|
mbedtls_x509_crt_free( &( pSslContext->clientCert ) );
|
||||||
mbedtls_pk_free( &( pSslContext->privKey ) );
|
mbedtls_pk_free( &( pSslContext->privKey ) );
|
||||||
|
mbedtls_entropy_free( &( pSslContext->entropyContext ) );
|
||||||
|
mbedtls_ctr_drbg_free( &( pSslContext->ctrDrgbContext ) );
|
||||||
mbedtls_ssl_config_free( &( pSslContext->config ) );
|
mbedtls_ssl_config_free( &( pSslContext->config ) );
|
||||||
}
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static int32_t setRootCa( SSLContext_t * pSslContext,
|
||||||
|
const uint8_t * pRootCa,
|
||||||
|
size_t rootCaSize )
|
||||||
|
{
|
||||||
|
int32_t mbedtlsError = -1;
|
||||||
|
|
||||||
|
configASSERT( pSslContext != NULL );
|
||||||
|
configASSERT( pRootCa != NULL );
|
||||||
|
|
||||||
|
/* Parse the server root CA certificate into the SSL context. */
|
||||||
|
mbedtlsError = mbedtls_x509_crt_parse( &( pSslContext->rootCa ),
|
||||||
|
pRootCa,
|
||||||
|
rootCaSize );
|
||||||
|
|
||||||
|
if( mbedtlsError != 0 )
|
||||||
|
{
|
||||||
|
LogError( ( "Failed to parse server root CA certificate: mbedTLSError= %s : %s.",
|
||||||
|
mbedtlsHighLevelCodeOrDefault( mbedtlsError ),
|
||||||
|
mbedtlsLowLevelCodeOrDefault( mbedtlsError ) ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mbedtls_ssl_conf_ca_chain( &( pSslContext->config ),
|
||||||
|
&( pSslContext->rootCa ),
|
||||||
|
NULL );
|
||||||
|
}
|
||||||
|
|
||||||
|
return mbedtlsError;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static int32_t setClientCertificate( SSLContext_t * pSslContext,
|
||||||
|
const uint8_t * pClientCert,
|
||||||
|
size_t clientCertSize )
|
||||||
|
{
|
||||||
|
int32_t mbedtlsError = -1;
|
||||||
|
|
||||||
|
configASSERT( pSslContext != NULL );
|
||||||
|
configASSERT( pClientCert != NULL );
|
||||||
|
|
||||||
|
/* Setup the client certificate. */
|
||||||
|
mbedtlsError = mbedtls_x509_crt_parse( &( pSslContext->clientCert ),
|
||||||
|
pClientCert,
|
||||||
|
clientCertSize );
|
||||||
|
|
||||||
|
if( mbedtlsError != 0 )
|
||||||
|
{
|
||||||
|
LogError( ( "Failed to parse the client certificate: mbedTLSError= %s : %s.",
|
||||||
|
mbedtlsHighLevelCodeOrDefault( mbedtlsError ),
|
||||||
|
mbedtlsLowLevelCodeOrDefault( mbedtlsError ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return mbedtlsError;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static int32_t setPrivateKey( SSLContext_t * pSslContext,
|
||||||
|
const uint8_t * pPrivateKeyPath,
|
||||||
|
size_t privateKeySize )
|
||||||
|
{
|
||||||
|
int32_t mbedtlsError = -1;
|
||||||
|
|
||||||
|
configASSERT( pSslContext != NULL );
|
||||||
|
configASSERT( pPrivateKeyPath != NULL );
|
||||||
|
|
||||||
|
/* Setup the client private key. */
|
||||||
|
mbedtlsError = mbedtls_pk_parse_key( &( pSslContext->privKey ),
|
||||||
|
pPrivateKeyPath,
|
||||||
|
privateKeySize,
|
||||||
|
NULL,
|
||||||
|
0 );
|
||||||
|
|
||||||
|
if( mbedtlsError != 0 )
|
||||||
|
{
|
||||||
|
LogError( ( "Failed to parse the client key: mbedTLSError= %s : %s.",
|
||||||
|
mbedtlsHighLevelCodeOrDefault( mbedtlsError ),
|
||||||
|
mbedtlsLowLevelCodeOrDefault( mbedtlsError ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return mbedtlsError;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static int32_t setCredentials( SSLContext_t * pSslContext,
|
||||||
|
const NetworkCredentials_t * pNetworkCredentials )
|
||||||
|
{
|
||||||
|
int32_t mbedtlsError = -1;
|
||||||
|
|
||||||
|
configASSERT( pSslContext != NULL );
|
||||||
|
configASSERT( pNetworkCredentials != NULL );
|
||||||
|
|
||||||
|
/* Set up the certificate security profile, starting from the default value. */
|
||||||
|
pSslContext->certProfile = mbedtls_x509_crt_profile_default;
|
||||||
|
|
||||||
|
/* Set SSL authmode and the RNG context. */
|
||||||
|
mbedtls_ssl_conf_authmode( &( pSslContext->config ),
|
||||||
|
MBEDTLS_SSL_VERIFY_REQUIRED );
|
||||||
|
mbedtls_ssl_conf_rng( &( pSslContext->config ),
|
||||||
|
mbedtls_ctr_drbg_random,
|
||||||
|
&( pSslContext->ctrDrgbContext ) );
|
||||||
|
mbedtls_ssl_conf_cert_profile( &( pSslContext->config ),
|
||||||
|
&( pSslContext->certProfile ) );
|
||||||
|
|
||||||
|
if( pNetworkCredentials->pRootCa != NULL )
|
||||||
|
{
|
||||||
|
mbedtlsError = setRootCa( pSslContext,
|
||||||
|
pNetworkCredentials->pRootCa,
|
||||||
|
pNetworkCredentials->rootCaSize );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ( pNetworkCredentials->pClientCert != NULL ) &&
|
||||||
|
( pNetworkCredentials->pPrivateKey != NULL ) )
|
||||||
|
{
|
||||||
|
if( mbedtlsError == 0 )
|
||||||
|
{
|
||||||
|
mbedtlsError = setClientCertificate( pSslContext,
|
||||||
|
pNetworkCredentials->pClientCert,
|
||||||
|
pNetworkCredentials->clientCertSize );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( mbedtlsError == 0 )
|
||||||
|
{
|
||||||
|
mbedtlsError = setPrivateKey( pSslContext,
|
||||||
|
pNetworkCredentials->pPrivateKey,
|
||||||
|
pNetworkCredentials->privateKeySize );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( mbedtlsError == 0 )
|
||||||
|
{
|
||||||
|
mbedtlsError = mbedtls_ssl_conf_own_cert( &( pSslContext->config ),
|
||||||
|
&( pSslContext->clientCert ),
|
||||||
|
&( pSslContext->privKey ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mbedtlsError;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void setOptionalConfigurations( SSLContext_t * pSslContext,
|
||||||
|
const char * pHostName,
|
||||||
|
const NetworkCredentials_t * pNetworkCredentials )
|
||||||
|
{
|
||||||
|
int32_t mbedtlsError = -1;
|
||||||
|
|
||||||
|
configASSERT( pSslContext != NULL );
|
||||||
|
configASSERT( pHostName != NULL );
|
||||||
|
configASSERT( pNetworkCredentials != NULL );
|
||||||
|
|
||||||
|
if( pNetworkCredentials->pAlpnProtos != NULL )
|
||||||
|
{
|
||||||
|
/* Include an application protocol list in the TLS ClientHello
|
||||||
|
* message. */
|
||||||
|
mbedtlsError = mbedtls_ssl_conf_alpn_protocols( &( pSslContext->config ),
|
||||||
|
pNetworkCredentials->pAlpnProtos );
|
||||||
|
|
||||||
|
if( mbedtlsError != 0 )
|
||||||
|
{
|
||||||
|
LogError( ( "Failed to configure ALPN protocol in mbed TLS: mbedTLSError= %s : %s.",
|
||||||
|
mbedtlsHighLevelCodeOrDefault( mbedtlsError ),
|
||||||
|
mbedtlsLowLevelCodeOrDefault( mbedtlsError ) ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Enable SNI if requested. */
|
||||||
|
if( pNetworkCredentials->disableSni == pdFALSE )
|
||||||
|
{
|
||||||
|
mbedtlsError = mbedtls_ssl_set_hostname( &( pSslContext->context ),
|
||||||
|
pHostName );
|
||||||
|
|
||||||
|
if( mbedtlsError != 0 )
|
||||||
|
{
|
||||||
|
LogError( ( "Failed to set server name: mbedTLSError= %s : %s.",
|
||||||
|
mbedtlsHighLevelCodeOrDefault( mbedtlsError ),
|
||||||
|
mbedtlsLowLevelCodeOrDefault( mbedtlsError ) ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
static TlsTransportStatus_t tlsSetup( NetworkContext_t * pNetworkContext,
|
static TlsTransportStatus_t tlsSetup( NetworkContext_t * pNetworkContext,
|
||||||
@ -155,7 +410,7 @@ static TlsTransportStatus_t tlsSetup( NetworkContext_t * pNetworkContext,
|
|||||||
const NetworkCredentials_t * pNetworkCredentials )
|
const NetworkCredentials_t * pNetworkCredentials )
|
||||||
{
|
{
|
||||||
TlsTransportStatus_t returnStatus = TLS_TRANSPORT_SUCCESS;
|
TlsTransportStatus_t returnStatus = TLS_TRANSPORT_SUCCESS;
|
||||||
int mbedtlsError = 0;
|
int32_t mbedtlsError = 0;
|
||||||
|
|
||||||
configASSERT( pNetworkContext != NULL );
|
configASSERT( pNetworkContext != NULL );
|
||||||
configASSERT( pHostName != NULL );
|
configASSERT( pHostName != NULL );
|
||||||
@ -182,111 +437,35 @@ static TlsTransportStatus_t tlsSetup( NetworkContext_t * pNetworkContext,
|
|||||||
|
|
||||||
if( returnStatus == TLS_TRANSPORT_SUCCESS )
|
if( returnStatus == TLS_TRANSPORT_SUCCESS )
|
||||||
{
|
{
|
||||||
/* Set up the certificate security profile, starting from the default value. */
|
mbedtlsError = setCredentials( &( pNetworkContext->sslContext ),
|
||||||
pNetworkContext->sslContext.certProfile = mbedtls_x509_crt_profile_default;
|
pNetworkCredentials );
|
||||||
|
|
||||||
/* 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 ),
|
|
||||||
mbedtls_ctr_drbg_random,
|
|
||||||
&ctrDrgbContext );
|
|
||||||
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 )
|
if( mbedtlsError != 0 )
|
||||||
{
|
{
|
||||||
LogError( ( "Failed to parse server root CA certificate: mbedTLSError= %s : %s.",
|
|
||||||
mbedtlsHighLevelCodeOrDefault( mbedtlsError ),
|
|
||||||
mbedtlsLowLevelCodeOrDefault( mbedtlsError ) ) );
|
|
||||||
|
|
||||||
returnStatus = TLS_TRANSPORT_INVALID_CREDENTIALS;
|
returnStatus = TLS_TRANSPORT_INVALID_CREDENTIALS;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mbedtls_ssl_conf_ca_chain( &( pNetworkContext->sslContext.config ),
|
/* Optionally set SNI and ALPN protocols. */
|
||||||
&( pNetworkContext->sslContext.rootCa ),
|
setOptionalConfigurations( &( pNetworkContext->sslContext ),
|
||||||
NULL );
|
pHostName,
|
||||||
|
pNetworkCredentials );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( returnStatus == TLS_TRANSPORT_SUCCESS )
|
return returnStatus;
|
||||||
{
|
}
|
||||||
if( ( pNetworkCredentials->pPrivateKey != NULL ) && ( pNetworkCredentials->pClientCert != NULL ) )
|
/*-----------------------------------------------------------*/
|
||||||
{
|
|
||||||
/* Setup the client private key. */
|
|
||||||
mbedtlsError = mbedtls_pk_parse_key( &( pNetworkContext->sslContext.privKey ),
|
|
||||||
pNetworkCredentials->pPrivateKey,
|
|
||||||
pNetworkCredentials->privateKeySize,
|
|
||||||
0,
|
|
||||||
0 );
|
|
||||||
|
|
||||||
if( mbedtlsError != 0 )
|
static TlsTransportStatus_t tlsHandshake( NetworkContext_t * pNetworkContext,
|
||||||
{
|
const NetworkCredentials_t * pNetworkCredentials )
|
||||||
LogError( ( "Failed to parse client certificate: mbedTLSError= %s : %s.",
|
{
|
||||||
mbedtlsHighLevelCodeOrDefault( mbedtlsError ),
|
TlsTransportStatus_t returnStatus = TLS_TRANSPORT_SUCCESS;
|
||||||
mbedtlsLowLevelCodeOrDefault( mbedtlsError ) ) );
|
int32_t mbedtlsError = 0;
|
||||||
|
|
||||||
returnStatus = TLS_TRANSPORT_INVALID_CREDENTIALS;
|
configASSERT( pNetworkContext != NULL );
|
||||||
}
|
configASSERT( pNetworkCredentials != NULL );
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Setup the client certificate. */
|
|
||||||
mbedtlsError = mbedtls_x509_crt_parse( &( pNetworkContext->sslContext.clientCert ),
|
|
||||||
pNetworkCredentials->pClientCert,
|
|
||||||
pNetworkCredentials->clientCertSize );
|
|
||||||
|
|
||||||
if( mbedtlsError != 0 )
|
|
||||||
{
|
|
||||||
LogError( ( "Failed to parse the client private key: mbedTLSError= %s : %s.",
|
|
||||||
mbedtlsHighLevelCodeOrDefault( mbedtlsError ),
|
|
||||||
mbedtlsLowLevelCodeOrDefault( mbedtlsError ) ) );
|
|
||||||
|
|
||||||
returnStatus = TLS_TRANSPORT_INVALID_CREDENTIALS;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
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 ),
|
|
||||||
( const char ** ) &( 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. */
|
/* Initialize the mbed TLS secured connection context. */
|
||||||
mbedtlsError = mbedtls_ssl_setup( &( pNetworkContext->sslContext.context ),
|
mbedtlsError = mbedtls_ssl_setup( &( pNetworkContext->sslContext.context ),
|
||||||
&( pNetworkContext->sslContext.config ) );
|
&( pNetworkContext->sslContext.config ) );
|
||||||
@ -302,32 +481,18 @@ static TlsTransportStatus_t tlsSetup( NetworkContext_t * pNetworkContext,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Set the underlying IO for the TLS connection. */
|
/* 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 ),
|
mbedtls_ssl_set_bio( &( pNetworkContext->sslContext.context ),
|
||||||
pNetworkContext->tcpSocket,
|
( void * ) pNetworkContext->tcpSocket,
|
||||||
mbedtls_platform_send,
|
mbedtls_platform_send,
|
||||||
mbedtls_platform_recv,
|
mbedtls_platform_recv,
|
||||||
NULL );
|
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( returnStatus == TLS_TRANSPORT_SUCCESS )
|
if( returnStatus == TLS_TRANSPORT_SUCCESS )
|
||||||
{
|
{
|
||||||
@ -346,27 +511,22 @@ static TlsTransportStatus_t tlsSetup( NetworkContext_t * pNetworkContext,
|
|||||||
|
|
||||||
returnStatus = TLS_TRANSPORT_HANDSHAKE_FAILED;
|
returnStatus = TLS_TRANSPORT_HANDSHAKE_FAILED;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if( returnStatus != TLS_TRANSPORT_SUCCESS )
|
|
||||||
{
|
|
||||||
sslContextFree( &( pNetworkContext->sslContext ) );
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LogInfo( ( "(Network connection %p) TLS handshake successful.",
|
LogInfo( ( "(Network connection %p) TLS handshake successful.",
|
||||||
pNetworkContext ) );
|
pNetworkContext ) );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return returnStatus;
|
return returnStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
static TlsTransportStatus_t initMbedtls( void )
|
static TlsTransportStatus_t initMbedtls( mbedtls_entropy_context * pEntropyContext,
|
||||||
|
mbedtls_ctr_drbg_context * pCtrDrgbContext )
|
||||||
{
|
{
|
||||||
TlsTransportStatus_t returnStatus = TLS_TRANSPORT_SUCCESS;
|
TlsTransportStatus_t returnStatus = TLS_TRANSPORT_SUCCESS;
|
||||||
int mbedtlsError = 0;
|
int32_t mbedtlsError = 0;
|
||||||
|
|
||||||
/* Set the mutex functions for mbed TLS thread safety. */
|
/* Set the mutex functions for mbed TLS thread safety. */
|
||||||
mbedtls_threading_set_alt( mbedtls_platform_mutex_init,
|
mbedtls_threading_set_alt( mbedtls_platform_mutex_init,
|
||||||
@ -375,11 +535,11 @@ static TlsTransportStatus_t initMbedtls( void )
|
|||||||
mbedtls_platform_mutex_unlock );
|
mbedtls_platform_mutex_unlock );
|
||||||
|
|
||||||
/* Initialize contexts for random number generation. */
|
/* Initialize contexts for random number generation. */
|
||||||
mbedtls_entropy_init( &entropyContext );
|
mbedtls_entropy_init( pEntropyContext );
|
||||||
mbedtls_ctr_drbg_init( &ctrDrgbContext );
|
mbedtls_ctr_drbg_init( pCtrDrgbContext );
|
||||||
|
|
||||||
/* Add a strong entropy source. At least one is required. */
|
/* Add a strong entropy source. At least one is required. */
|
||||||
mbedtlsError = mbedtls_entropy_add_source( &entropyContext,
|
mbedtlsError = mbedtls_entropy_add_source( pEntropyContext,
|
||||||
mbedtls_platform_entropy_poll,
|
mbedtls_platform_entropy_poll,
|
||||||
NULL,
|
NULL,
|
||||||
32,
|
32,
|
||||||
@ -396,9 +556,9 @@ static TlsTransportStatus_t initMbedtls( void )
|
|||||||
if( returnStatus == TLS_TRANSPORT_SUCCESS )
|
if( returnStatus == TLS_TRANSPORT_SUCCESS )
|
||||||
{
|
{
|
||||||
/* Seed the random number generator. */
|
/* Seed the random number generator. */
|
||||||
mbedtlsError = mbedtls_ctr_drbg_seed( &ctrDrgbContext,
|
mbedtlsError = mbedtls_ctr_drbg_seed( pCtrDrgbContext,
|
||||||
mbedtls_entropy_func,
|
mbedtls_entropy_func,
|
||||||
&entropyContext,
|
pEntropyContext,
|
||||||
NULL,
|
NULL,
|
||||||
0 );
|
0 );
|
||||||
|
|
||||||
@ -418,7 +578,6 @@ static TlsTransportStatus_t initMbedtls( void )
|
|||||||
|
|
||||||
return returnStatus;
|
return returnStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
TlsTransportStatus_t TLS_FreeRTOS_Connect( NetworkContext_t * pNetworkContext,
|
TlsTransportStatus_t TLS_FreeRTOS_Connect( NetworkContext_t * pNetworkContext,
|
||||||
@ -447,6 +606,10 @@ TlsTransportStatus_t TLS_FreeRTOS_Connect( NetworkContext_t * pNetworkContext,
|
|||||||
LogError( ( "pRootCa cannot be NULL." ) );
|
LogError( ( "pRootCa cannot be NULL." ) );
|
||||||
returnStatus = TLS_TRANSPORT_INVALID_PARAMETER;
|
returnStatus = TLS_TRANSPORT_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Empty else for MISRA 15.7 compliance. */
|
||||||
|
}
|
||||||
|
|
||||||
/* Establish a TCP connection with the server. */
|
/* Establish a TCP connection with the server. */
|
||||||
if( returnStatus == TLS_TRANSPORT_SUCCESS )
|
if( returnStatus == TLS_TRANSPORT_SUCCESS )
|
||||||
@ -469,21 +632,31 @@ TlsTransportStatus_t TLS_FreeRTOS_Connect( NetworkContext_t * pNetworkContext,
|
|||||||
/* Initialize mbedtls. */
|
/* Initialize mbedtls. */
|
||||||
if( returnStatus == TLS_TRANSPORT_SUCCESS )
|
if( returnStatus == TLS_TRANSPORT_SUCCESS )
|
||||||
{
|
{
|
||||||
returnStatus = initMbedtls();
|
returnStatus = initMbedtls( &( pNetworkContext->sslContext.entropyContext ),
|
||||||
|
&( pNetworkContext->sslContext.ctrDrgbContext ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Perform TLS handshake. */
|
/* Initialize TLS contexts and set credentials. */
|
||||||
if( returnStatus == TLS_TRANSPORT_SUCCESS )
|
if( returnStatus == TLS_TRANSPORT_SUCCESS )
|
||||||
{
|
{
|
||||||
returnStatus = tlsSetup( pNetworkContext, pHostName, pNetworkCredentials );
|
returnStatus = tlsSetup( pNetworkContext, pHostName, pNetworkCredentials );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Perform TLS handshake. */
|
||||||
|
if( returnStatus == TLS_TRANSPORT_SUCCESS )
|
||||||
|
{
|
||||||
|
returnStatus = tlsHandshake( pNetworkContext, pNetworkCredentials );
|
||||||
|
}
|
||||||
|
|
||||||
/* Clean up on failure. */
|
/* Clean up on failure. */
|
||||||
if( returnStatus != TLS_TRANSPORT_SUCCESS )
|
if( returnStatus != TLS_TRANSPORT_SUCCESS )
|
||||||
{
|
{
|
||||||
if( pNetworkContext->tcpSocket != FREERTOS_INVALID_SOCKET )
|
sslContextFree( &( pNetworkContext->sslContext ) );
|
||||||
|
|
||||||
|
if( ( pNetworkContext != NULL ) &&
|
||||||
|
( pNetworkContext->tcpSocket != FREERTOS_INVALID_SOCKET ) )
|
||||||
{
|
{
|
||||||
FreeRTOS_closesocket( pNetworkContext->tcpSocket );
|
( void ) FreeRTOS_closesocket( pNetworkContext->tcpSocket );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -495,7 +668,6 @@ TlsTransportStatus_t TLS_FreeRTOS_Connect( NetworkContext_t * pNetworkContext,
|
|||||||
|
|
||||||
return returnStatus;
|
return returnStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void TLS_FreeRTOS_Disconnect( NetworkContext_t * pNetworkContext )
|
void TLS_FreeRTOS_Disconnect( NetworkContext_t * pNetworkContext )
|
||||||
@ -537,14 +709,9 @@ void TLS_FreeRTOS_Disconnect( NetworkContext_t * pNetworkContext )
|
|||||||
/* Free mbed TLS contexts. */
|
/* Free mbed TLS contexts. */
|
||||||
sslContextFree( &( pNetworkContext->sslContext ) );
|
sslContextFree( &( pNetworkContext->sslContext ) );
|
||||||
|
|
||||||
/* Free the contexts for random number generation. */
|
|
||||||
mbedtls_ctr_drbg_free( &ctrDrgbContext );
|
|
||||||
mbedtls_entropy_free( &entropyContext );
|
|
||||||
|
|
||||||
/* Clear the mutex functions for mbed TLS thread safety. */
|
/* Clear the mutex functions for mbed TLS thread safety. */
|
||||||
mbedtls_threading_free_alt();
|
mbedtls_threading_free_alt();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
int32_t TLS_FreeRTOS_recv( NetworkContext_t * pNetworkContext,
|
int32_t TLS_FreeRTOS_recv( NetworkContext_t * pNetworkContext,
|
||||||
@ -583,7 +750,6 @@ int32_t TLS_FreeRTOS_recv( NetworkContext_t * pNetworkContext,
|
|||||||
|
|
||||||
return tlsStatus;
|
return tlsStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
int32_t TLS_FreeRTOS_send( NetworkContext_t * pNetworkContext,
|
int32_t TLS_FreeRTOS_send( NetworkContext_t * pNetworkContext,
|
||||||
|
@ -131,7 +131,7 @@ static TlsTransportStatus_t initMbedtls( void );
|
|||||||
*
|
*
|
||||||
* @return Zero on success.
|
* @return Zero on success.
|
||||||
*/
|
*/
|
||||||
static int generateRandomBytes( void * pvCtx,
|
static int32_t generateRandomBytes( void * pvCtx,
|
||||||
unsigned char * pucRandom,
|
unsigned char * pucRandom,
|
||||||
size_t xRandomLength );
|
size_t xRandomLength );
|
||||||
|
|
||||||
@ -175,13 +175,13 @@ static CK_RV initializeClientKeys( SSLContext_t * pxCtx );
|
|||||||
*
|
*
|
||||||
* @return Zero on success.
|
* @return Zero on success.
|
||||||
*/
|
*/
|
||||||
static int privateKeySigningCallback( void * pvContext,
|
static int32_t privateKeySigningCallback( void * pvContext,
|
||||||
mbedtls_md_type_t xMdAlg,
|
mbedtls_md_type_t xMdAlg,
|
||||||
const unsigned char * pucHash,
|
const unsigned char * pucHash,
|
||||||
size_t xHashLen,
|
size_t xHashLen,
|
||||||
unsigned char * pucSig,
|
unsigned char * pucSig,
|
||||||
size_t * pxSigLen,
|
size_t * pxSigLen,
|
||||||
int ( * piRng )( void *,
|
int32_t ( * piRng )( void *,
|
||||||
unsigned char *,
|
unsigned char *,
|
||||||
size_t ),
|
size_t ),
|
||||||
void * pvRng );
|
void * pvRng );
|
||||||
@ -222,7 +222,7 @@ static TlsTransportStatus_t tlsSetup( NetworkContext_t * pNetworkContext,
|
|||||||
const NetworkCredentials_t * pNetworkCredentials )
|
const NetworkCredentials_t * pNetworkCredentials )
|
||||||
{
|
{
|
||||||
TlsTransportStatus_t returnStatus = TLS_TRANSPORT_SUCCESS;
|
TlsTransportStatus_t returnStatus = TLS_TRANSPORT_SUCCESS;
|
||||||
int mbedtlsError = 0;
|
int32_t mbedtlsError = 0;
|
||||||
CK_RV xResult = CKR_OK;
|
CK_RV xResult = CKR_OK;
|
||||||
|
|
||||||
configASSERT( pNetworkContext != NULL );
|
configASSERT( pNetworkContext != NULL );
|
||||||
@ -319,7 +319,7 @@ static TlsTransportStatus_t tlsSetup( NetworkContext_t * pNetworkContext,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mbedtls_ssl_conf_own_cert( &( pNetworkContext->sslContext.config ),
|
( void ) mbedtls_ssl_conf_own_cert( &( pNetworkContext->sslContext.config ),
|
||||||
&( pNetworkContext->sslContext.clientCert ),
|
&( pNetworkContext->sslContext.clientCert ),
|
||||||
&( pNetworkContext->sslContext.privKey ) );
|
&( pNetworkContext->sslContext.privKey ) );
|
||||||
}
|
}
|
||||||
@ -331,7 +331,7 @@ static TlsTransportStatus_t tlsSetup( NetworkContext_t * pNetworkContext,
|
|||||||
/* Include an application protocol list in the TLS ClientHello
|
/* Include an application protocol list in the TLS ClientHello
|
||||||
* message. */
|
* message. */
|
||||||
mbedtlsError = mbedtls_ssl_conf_alpn_protocols( &( pNetworkContext->sslContext.config ),
|
mbedtlsError = mbedtls_ssl_conf_alpn_protocols( &( pNetworkContext->sslContext.config ),
|
||||||
( const char ** ) &( pNetworkCredentials->pAlpnProtos ) );
|
pNetworkCredentials->pAlpnProtos );
|
||||||
|
|
||||||
if( mbedtlsError != 0 )
|
if( mbedtlsError != 0 )
|
||||||
{
|
{
|
||||||
@ -360,8 +360,14 @@ static TlsTransportStatus_t tlsSetup( NetworkContext_t * pNetworkContext,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Set the underlying IO for the TLS connection. */
|
/* 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 ),
|
mbedtls_ssl_set_bio( &( pNetworkContext->sslContext.context ),
|
||||||
pNetworkContext->tcpSocket,
|
( void * ) pNetworkContext->tcpSocket,
|
||||||
mbedtls_platform_send,
|
mbedtls_platform_send,
|
||||||
mbedtls_platform_recv,
|
mbedtls_platform_recv,
|
||||||
NULL );
|
NULL );
|
||||||
@ -441,7 +447,7 @@ static TlsTransportStatus_t initMbedtls( void )
|
|||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
static int generateRandomBytes( void * pvCtx,
|
static int32_t generateRandomBytes( void * pvCtx,
|
||||||
unsigned char * pucRandom,
|
unsigned char * pucRandom,
|
||||||
size_t xRandomLength )
|
size_t xRandomLength )
|
||||||
{
|
{
|
||||||
@ -645,19 +651,19 @@ static CK_RV initializeClientKeys( SSLContext_t * pxCtx )
|
|||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
static int privateKeySigningCallback( void * pvContext,
|
static int32_t privateKeySigningCallback( void * pvContext,
|
||||||
mbedtls_md_type_t xMdAlg,
|
mbedtls_md_type_t xMdAlg,
|
||||||
const unsigned char * pucHash,
|
const unsigned char * pucHash,
|
||||||
size_t xHashLen,
|
size_t xHashLen,
|
||||||
unsigned char * pucSig,
|
unsigned char * pucSig,
|
||||||
size_t * pxSigLen,
|
size_t * pxSigLen,
|
||||||
int ( * piRng )( void *,
|
int32_t ( * piRng )( void *,
|
||||||
unsigned char *,
|
unsigned char *,
|
||||||
size_t ),
|
size_t ),
|
||||||
void * pvRng )
|
void * pvRng )
|
||||||
{
|
{
|
||||||
CK_RV xResult = CKR_OK;
|
CK_RV xResult = CKR_OK;
|
||||||
int lFinalResult = 0;
|
int32_t lFinalResult = 0;
|
||||||
SSLContext_t * pxTLSContext = ( SSLContext_t * ) pvContext;
|
SSLContext_t * pxTLSContext = ( SSLContext_t * ) pvContext;
|
||||||
CK_MECHANISM xMech = { 0 };
|
CK_MECHANISM xMech = { 0 };
|
||||||
CK_BYTE xToBeSigned[ 256 ];
|
CK_BYTE xToBeSigned[ 256 ];
|
||||||
@ -766,6 +772,10 @@ TlsTransportStatus_t TLS_FreeRTOS_Connect( NetworkContext_t * pNetworkContext,
|
|||||||
LogError( ( "pRootCa cannot be NULL." ) );
|
LogError( ( "pRootCa cannot be NULL." ) );
|
||||||
returnStatus = TLS_TRANSPORT_INVALID_PARAMETER;
|
returnStatus = TLS_TRANSPORT_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Empty else for MISRA 15.7 compliance. */
|
||||||
|
}
|
||||||
|
|
||||||
/* Establish a TCP connection with the server. */
|
/* Establish a TCP connection with the server. */
|
||||||
if( returnStatus == TLS_TRANSPORT_SUCCESS )
|
if( returnStatus == TLS_TRANSPORT_SUCCESS )
|
||||||
@ -800,9 +810,10 @@ TlsTransportStatus_t TLS_FreeRTOS_Connect( NetworkContext_t * pNetworkContext,
|
|||||||
/* Clean up on failure. */
|
/* Clean up on failure. */
|
||||||
if( returnStatus != TLS_TRANSPORT_SUCCESS )
|
if( returnStatus != TLS_TRANSPORT_SUCCESS )
|
||||||
{
|
{
|
||||||
if( pNetworkContext->tcpSocket != FREERTOS_INVALID_SOCKET )
|
if( ( pNetworkContext != NULL ) &&
|
||||||
|
( pNetworkContext->tcpSocket != FREERTOS_INVALID_SOCKET ) )
|
||||||
{
|
{
|
||||||
FreeRTOS_closesocket( pNetworkContext->tcpSocket );
|
( void ) FreeRTOS_closesocket( pNetworkContext->tcpSocket );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -128,7 +128,7 @@
|
|||||||
*
|
*
|
||||||
* // If pRetryParams->maxRetryAttempts is set to 0, try forever.
|
* // If pRetryParams->maxRetryAttempts is set to 0, try forever.
|
||||||
* if( ( pRetryParams->attemptsDone < pRetryParams->maxRetryAttempts ) ||
|
* if( ( pRetryParams->attemptsDone < pRetryParams->maxRetryAttempts ) ||
|
||||||
* ( 0 == pRetryParams->maxRetryAttempts ) )
|
* ( 0U == pRetryParams->maxRetryAttempts ) )
|
||||||
* {
|
* {
|
||||||
* // Choose a random value for back-off time between 0 and the max jitter value.
|
* // Choose a random value for back-off time between 0 and the max jitter value.
|
||||||
* backOffDelay = rand() % pRetryParams->nextJitterMax;
|
* backOffDelay = rand() % pRetryParams->nextJitterMax;
|
||||||
|
@ -19,6 +19,11 @@
|
|||||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file transport_interface.h
|
||||||
|
* @brief Transport interface definitions to send and receive data over the
|
||||||
|
* network.
|
||||||
|
*/
|
||||||
#ifndef TRANSPORT_INTERFACE_H_
|
#ifndef TRANSPORT_INTERFACE_H_
|
||||||
#define TRANSPORT_INTERFACE_H_
|
#define TRANSPORT_INTERFACE_H_
|
||||||
|
|
||||||
@ -26,14 +31,131 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The NetworkContext is an incomplete type. An implementation of this
|
* @transportpage
|
||||||
* interface must define NetworkContext as per the requirements. This context
|
* @brief The transport interface definition.
|
||||||
* is passed into the network interface functions.
|
*
|
||||||
|
* @transportsectionoverview
|
||||||
|
*
|
||||||
|
* The transport interface is a set of APIs that must be implemented using an
|
||||||
|
* external transport layer protocol. The transport interface is defined in
|
||||||
|
* @ref transport_interface.h. This interface allows protocols like MQTT and
|
||||||
|
* HTTP to send and receive data over the transport layer. This
|
||||||
|
* interface does not handle connection and disconnection to the server of
|
||||||
|
* interest. The connection, disconnection, and other transport settings, like
|
||||||
|
* timeout and TLS setup, must be handled in the user application.
|
||||||
|
* <br>
|
||||||
|
*
|
||||||
|
* The functions that must be implemented are:<br>
|
||||||
|
* - [Transport Receive](@ref TransportRecv_t)
|
||||||
|
* - [Transport Send](@ref TransportSend_t)
|
||||||
|
*
|
||||||
|
* Each of the functions above take in an opaque context @ref NetworkContext_t.
|
||||||
|
* The functions above and the context are also grouped together in the
|
||||||
|
* @ref TransportInterface_t structure:<br><br>
|
||||||
|
* @snippet this define_transportinterface
|
||||||
|
* <br>
|
||||||
|
*
|
||||||
|
* @transportsectionimplementation
|
||||||
|
*
|
||||||
|
* The following steps give guidance on implementing the transport interface:
|
||||||
|
*
|
||||||
|
* -# Implementing @ref NetworkContext_t<br><br>
|
||||||
|
* @snippet this define_networkcontext
|
||||||
|
* <br>
|
||||||
|
* @ref NetworkContext_t is the incomplete type <b>struct NetworkContext</b>.
|
||||||
|
* The implemented struct NetworkContext must contain all of the information
|
||||||
|
* that is needed to receive and send data with the @ref TransportRecv_t
|
||||||
|
* and the @ref TransportSend_t implementations.<br>
|
||||||
|
* In the case of TLS over TCP, struct NetworkContext is typically implemented
|
||||||
|
* with the TCP socket context and a TLS context.<br><br>
|
||||||
|
* <b>Example code:</b>
|
||||||
|
* @code{c}
|
||||||
|
* struct NetworkContext
|
||||||
|
* {
|
||||||
|
* struct MyTCPSocketContext tcpSocketContext;
|
||||||
|
* struct MyTLSContext tlsContext;
|
||||||
|
* };
|
||||||
|
* @endcode
|
||||||
|
* <br>
|
||||||
|
* -# Implementing @ref TransportRecv_t<br><br>
|
||||||
|
* @snippet this define_transportrecv
|
||||||
|
* <br>
|
||||||
|
* This function is expected to populate a buffer, with bytes received from the
|
||||||
|
* transport, and return the number of bytes placed in the buffer.
|
||||||
|
* In the case of TLS over TCP, @ref TransportRecv_t is typically implemented by
|
||||||
|
* calling the TLS layer function to receive data. In case of plaintext TCP
|
||||||
|
* without TLS, it is typically implemented by calling the TCP layer receive
|
||||||
|
* function. @ref TransportRecv_t may be invoked multiple times by the protocol
|
||||||
|
* library, if fewer bytes than were requested to receive are returned.
|
||||||
|
* <br><br>
|
||||||
|
* <b>Example code:</b>
|
||||||
|
* @code{c}
|
||||||
|
* int32_t myNetworkRecvImplementation( const NetworkContext_t * pNetworkContext,
|
||||||
|
* void * pBuffer,
|
||||||
|
* size_t bytesToRecv )
|
||||||
|
* {
|
||||||
|
* int32_t bytesReceived = 0;
|
||||||
|
* bytesReceived = TLSRecv( pNetworkContext->tlsContext,
|
||||||
|
* pBuffer,
|
||||||
|
* bytesToRecv,
|
||||||
|
* MY_SOCKET_TIMEOUT );
|
||||||
|
* if( bytesReceived < 0 )
|
||||||
|
* {
|
||||||
|
* // Handle socket error.
|
||||||
|
* }
|
||||||
|
* // Handle other cases.
|
||||||
|
*
|
||||||
|
* return bytesReceived;
|
||||||
|
* }
|
||||||
|
* @endcode
|
||||||
|
* <br>
|
||||||
|
* -# Implementing @ref TransportSend_t<br><br>
|
||||||
|
* @snippet this define_transportsend
|
||||||
|
* <br>
|
||||||
|
* This function is expected to send the bytes, in the given buffer over the
|
||||||
|
* transport, and return the number of bytes sent.
|
||||||
|
* In the case of TLS over TCP, @ref TransportSend_t is typically implemented by
|
||||||
|
* calling the TLS layer function to send data. In case of plaintext TCP
|
||||||
|
* without TLS, it is typically implemented by calling the TCP layer send
|
||||||
|
* function. @ref TransportSend_t may be invoked multiple times by the protocol
|
||||||
|
* library, if fewer bytes than were requested to send are returned.
|
||||||
|
* <br><br>
|
||||||
|
* <b>Example code:</b>
|
||||||
|
* @code{c}
|
||||||
|
* int32_t myNetworkSendImplementation( const NetworkContext_t * pNetworkContext,
|
||||||
|
* const void * pBuffer,
|
||||||
|
* size_t bytesToSend )
|
||||||
|
* {
|
||||||
|
* int32_t bytesSent = 0;
|
||||||
|
* bytesSent = TLSSend( pNetworkContext->tlsContext,
|
||||||
|
* pBuffer,
|
||||||
|
* bytesToSend,
|
||||||
|
* MY_SOCKET_TIMEOUT );
|
||||||
|
* if( bytesSent < 0 )
|
||||||
|
* {
|
||||||
|
* // Handle socket error.
|
||||||
|
* }
|
||||||
|
* // Handle other cases.
|
||||||
|
*
|
||||||
|
* return bytesSent;
|
||||||
|
* }
|
||||||
|
* @endcode
|
||||||
*/
|
*/
|
||||||
struct NetworkContext;
|
|
||||||
typedef struct NetworkContext NetworkContext_t;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @transportstruct
|
||||||
|
* @typedef NetworkContext_t
|
||||||
|
* @brief The NetworkContext is an incomplete type. An implementation of this
|
||||||
|
* interface must define struct NetworkContext for the system requirements.
|
||||||
|
* This context is passed into the network interface functions.
|
||||||
|
*/
|
||||||
|
/* @[define_networkcontext] */
|
||||||
|
struct NetworkContext;
|
||||||
|
typedef struct NetworkContext NetworkContext_t;
|
||||||
|
/* @[define_networkcontext] */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @transportcallback
|
||||||
* @brief Transport interface for receiving data on the network.
|
* @brief Transport interface for receiving data on the network.
|
||||||
*
|
*
|
||||||
* @param[in] pNetworkContext Implementation-defined network context.
|
* @param[in] pNetworkContext Implementation-defined network context.
|
||||||
@ -42,11 +164,14 @@ typedef struct NetworkContext NetworkContext_t;
|
|||||||
*
|
*
|
||||||
* @return The number of bytes received or a negative error code.
|
* @return The number of bytes received or a negative error code.
|
||||||
*/
|
*/
|
||||||
typedef int32_t ( * TransportRecv_t )( NetworkContext_t * pNetworkContext,
|
/* @[define_transportrecv] */
|
||||||
|
typedef int32_t ( * TransportRecv_t )( const NetworkContext_t * pNetworkContext,
|
||||||
void * pBuffer,
|
void * pBuffer,
|
||||||
size_t bytesToRecv );
|
size_t bytesToRecv );
|
||||||
|
/* @[define_transportrecv] */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @transportcallback
|
||||||
* @brief Transport interface for sending data over the network.
|
* @brief Transport interface for sending data over the network.
|
||||||
*
|
*
|
||||||
* @param[in] pNetworkContext Implementation-defined network context.
|
* @param[in] pNetworkContext Implementation-defined network context.
|
||||||
@ -55,18 +180,23 @@ typedef int32_t ( * TransportRecv_t )( NetworkContext_t * pNetworkContext,
|
|||||||
*
|
*
|
||||||
* @return The number of bytes sent or a negative error code.
|
* @return The number of bytes sent or a negative error code.
|
||||||
*/
|
*/
|
||||||
typedef int32_t ( * TransportSend_t )( NetworkContext_t * pNetworkContext,
|
/* @[define_transportsend] */
|
||||||
|
typedef int32_t ( * TransportSend_t )( const NetworkContext_t * pNetworkContext,
|
||||||
const void * pBuffer,
|
const void * pBuffer,
|
||||||
size_t bytesToSend );
|
size_t bytesToSend );
|
||||||
|
/* @[define_transportsend] */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @transportstruct
|
||||||
* @brief The transport layer interface.
|
* @brief The transport layer interface.
|
||||||
*/
|
*/
|
||||||
|
/* @[define_transportinterface] */
|
||||||
typedef struct TransportInterface
|
typedef struct TransportInterface
|
||||||
{
|
{
|
||||||
TransportRecv_t recv; /**< Transport receive interface. */
|
TransportRecv_t recv; /**< Transport receive interface. */
|
||||||
TransportSend_t send; /**< Transport send interface. */
|
TransportSend_t send; /**< Transport send interface. */
|
||||||
NetworkContext_t * pNetworkContext; /**< Implementation-defined network context. */
|
NetworkContext_t * pNetworkContext; /**< Implementation-defined network context. */
|
||||||
} TransportInterface_t;
|
} TransportInterface_t;
|
||||||
|
/* @[define_transportinterface] */
|
||||||
|
|
||||||
#endif /* ifndef TRANSPORT_INTERFACE_H_ */
|
#endif /* ifndef TRANSPORT_INTERFACE_H_ */
|
||||||
|
Reference in New Issue
Block a user