590 lines
18 KiB
C
Executable File
590 lines
18 KiB
C
Executable File
/*
|
|
* Amazon FreeRTOS TLS V1.1.0
|
|
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
* this software and associated documentation files (the "Software"), to deal in
|
|
* the Software without restriction, including without limitation the rights to
|
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
|
* subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in all
|
|
* copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
* 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
|
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
*
|
|
* http://aws.amazon.com/freertos
|
|
* http://www.FreeRTOS.org
|
|
*/
|
|
|
|
/* FreeRTOS includes. */
|
|
#include "FreeRTOS.h"
|
|
#include "FreeRTOSIPConfig.h"
|
|
#include "aws_tls.h"
|
|
#include "aws_crypto.h"
|
|
#include "aws_pkcs11.h"
|
|
#include "task.h"
|
|
#include "aws_clientcredential.h"
|
|
#include "aws_default_root_certificates.h"
|
|
|
|
#ifdef WOLF_AWSTLS
|
|
|
|
/* wolfSSL library (github.com/wolfSSL/wolfssl) */
|
|
#include <wolfssl/wolfcrypt/settings.h>
|
|
#include <wolfssl/ssl.h>
|
|
#include <wolfssl/wolfcrypt/sha256.h>
|
|
#include <wolfssl/wolfcrypt/sha.h>
|
|
#include <wolfssl/wolfcrypt/asn_public.h>
|
|
#include <wolfssl/wolfcrypt/coding.h>
|
|
#include <wolfssl/wolfcrypt/random.h>
|
|
#include <wolfssl/wolfcrypt/ecc.h>
|
|
#include <wolfssl/wolfcrypt/rsa.h>
|
|
#include <wolfssl/wolfcrypt/error-crypt.h>
|
|
|
|
/* C runtime includes. */
|
|
#include <string.h>
|
|
#include <time.h>
|
|
#include <stdio.h>
|
|
|
|
/**
|
|
* @brief Internal context structure.
|
|
*
|
|
* @param[in] pcDestination Server location, can be a DNS name or IP address.
|
|
* @param[in] pcServerCertificate Server X.509 certificate in PEM format to trust.
|
|
* @param[in] ulServerCertificateLength Length in bytes of the server certificate.
|
|
* @param[in] pxNetworkRecv Callback for receiving data on an open TCP socket.
|
|
* @param[in] pxNetworkSend Callback for sending data on an open TCP socket.
|
|
* @param[in] pvCallerContext Opaque pointer provided by caller for above callbacks.
|
|
* @param[out] ctx wolfSSL context for creating connections
|
|
* @param[out] ssl wolfSSL object for connection
|
|
* @param[out] pxP11FunctionList PKCS#11 function list structure.
|
|
* @param[out] xP11Session PKCS#11 session context.
|
|
* @param[out] xP11PrivateKey PKCS#11 private key context.
|
|
* @param[out] ulP11ModulusBytes Number of bytes in the client private key modulus.
|
|
*/
|
|
typedef struct TLSContext
|
|
{
|
|
const char * pcDestination;
|
|
const char * pcServerCertificate;
|
|
uint32_t ulServerCertificateLength;
|
|
const char ** ppcAlpnProtocols;
|
|
uint32_t ulAlpnProtocolsCount;
|
|
|
|
NetworkRecv_t pxNetworkRecv;
|
|
NetworkSend_t pxNetworkSend;
|
|
void * pvCallerContext;
|
|
|
|
/* wolfSSL */
|
|
WOLFSSL_CTX* ctx;
|
|
WOLFSSL* ssl;
|
|
|
|
/* PKCS#11. */
|
|
CK_FUNCTION_LIST_PTR pxP11FunctionList;
|
|
CK_SESSION_HANDLE xP11Session;
|
|
CK_OBJECT_HANDLE xP11PrivateKey;
|
|
CK_ULONG ulP11ModulusBytes;
|
|
} TLSContext_t;
|
|
|
|
/*
|
|
* Helper routines.
|
|
*/
|
|
|
|
/**
|
|
* @brief Network send callback shim.
|
|
*
|
|
* @param[in] pvContext Caller context.
|
|
* @param[in] pucData Byte buffer to send.
|
|
* @param[in] xDataLength Length of byte buffer to send.
|
|
*
|
|
* @return Number of bytes sent, or a negative value on error.
|
|
*/
|
|
static int prvNetworkSend(WOLFSSL* ssl, char *pucData, int xDataLength,
|
|
void *pvContext)
|
|
{
|
|
TLSContext_t * pCtx = ( TLSContext_t * ) pvContext; /*lint !e9087 !e9079 Allow casting void* to other types. */
|
|
(void)ssl;
|
|
|
|
return ( int ) pCtx->pxNetworkSend( pCtx->pvCallerContext, (const byte*)pucData, xDataLength );
|
|
}
|
|
|
|
/**
|
|
* @brief Network receive callback shim.
|
|
*
|
|
* @param[in] pvContext Caller context.
|
|
* @param[out] pucReceiveBuffer Byte buffer to receive into.
|
|
* @param[in] xReceiveLength Length of byte buffer for receive.
|
|
*
|
|
* @return Number of bytes received, or a negative value on error.
|
|
*/
|
|
static int prvNetworkRecv(WOLFSSL* ssl, char *pucReceiveBuffer, int xReceiveLength,
|
|
void *pvContext)
|
|
{
|
|
TLSContext_t * pCtx = ( TLSContext_t * ) pvContext; /*lint !e9087 !e9079 Allow casting void* to other types. */
|
|
(void)ssl;
|
|
|
|
return ( int ) pCtx->pxNetworkRecv( pCtx->pvCallerContext, (byte*)pucReceiveBuffer, xReceiveLength );
|
|
}
|
|
|
|
|
|
static int prvCheckCertificate(int preverify, WOLFSSL_X509_STORE_CTX* store)
|
|
{
|
|
char buffer[WOLFSSL_MAX_ERROR_SZ];
|
|
(void)preverify;
|
|
|
|
printf("In verification callback, error = %d, %s\n", store->error,
|
|
wolfSSL_ERR_error_string(store->error, buffer));
|
|
printf("Subject's domain name is %s\n", store->domain);
|
|
|
|
if (store->error == ASN_BEFORE_DATE_E || store->error == ASN_AFTER_DATE_E) {
|
|
printf("Overriding cert date error as example for bad clock testing\n");
|
|
return 1;
|
|
}
|
|
printf("Cert error is not date error, not overriding\n");
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief Helper for setting up potentially hardware-based cryptographic context
|
|
* for the client TLS certificate and private key.
|
|
*
|
|
* @param Caller context.
|
|
*
|
|
* @return Zero on success.
|
|
*/
|
|
static int prvInitializeClientCredential( TLSContext_t * pCtx )
|
|
{
|
|
BaseType_t xResult = 0;
|
|
CK_C_GetFunctionList pxCkGetFunctionList = NULL;
|
|
CK_SLOT_ID xSlotId = 0;
|
|
CK_ULONG ulCount = 1;
|
|
CK_ATTRIBUTE xTemplate = { 0 };
|
|
CK_OBJECT_CLASS xObjClass = 0;
|
|
CK_OBJECT_HANDLE xCertObj = 0;
|
|
CK_BYTE * pucCertificate = NULL;
|
|
vedCliKey cliKey;
|
|
|
|
/* Ensure that the PKCS#11 module is initialized. */
|
|
if( 0 == xResult )
|
|
{
|
|
pxCkGetFunctionList = C_GetFunctionList;
|
|
xResult = ( BaseType_t ) pxCkGetFunctionList( &pCtx->pxP11FunctionList );
|
|
}
|
|
|
|
if( 0 == xResult )
|
|
{
|
|
xResult = ( BaseType_t ) pCtx->pxP11FunctionList->C_Initialize( NULL );
|
|
}
|
|
|
|
/* Get the default private key storage ID. */
|
|
if( 0 == xResult )
|
|
{
|
|
xResult = ( BaseType_t ) pCtx->pxP11FunctionList->C_GetSlotList( CK_TRUE, &xSlotId, &ulCount );
|
|
}
|
|
|
|
/* Start a private session with the P#11 module. */
|
|
if( 0 == xResult )
|
|
{
|
|
xResult = ( BaseType_t ) pCtx->pxP11FunctionList->C_OpenSession( xSlotId,
|
|
0,
|
|
NULL,
|
|
NULL,
|
|
&pCtx->xP11Session );
|
|
}
|
|
|
|
/* Enumerate the first private key. */
|
|
if( 0 == xResult )
|
|
{
|
|
xTemplate.type = CKA_CLASS;
|
|
xTemplate.ulValueLen = sizeof( CKA_CLASS );
|
|
xTemplate.pValue = &xObjClass;
|
|
xObjClass = CKO_PRIVATE_KEY;
|
|
xResult = ( BaseType_t ) pCtx->pxP11FunctionList->C_FindObjectsInit( pCtx->xP11Session, &xTemplate, 1 );
|
|
}
|
|
|
|
if( 0 == xResult )
|
|
{
|
|
xResult = ( BaseType_t ) pCtx->pxP11FunctionList->C_FindObjects( pCtx->xP11Session, &pCtx->xP11PrivateKey, 1, &ulCount );
|
|
}
|
|
|
|
if( 0 == xResult )
|
|
{
|
|
xResult = ( BaseType_t ) pCtx->pxP11FunctionList->C_FindObjectsFinal( pCtx->xP11Session );
|
|
}
|
|
|
|
/* Get the internal key context. */
|
|
if( 0 == xResult )
|
|
{
|
|
xTemplate.type = CKA_VENDOR_DEFINED;
|
|
xTemplate.ulValueLen = sizeof( cliKey );
|
|
xTemplate.pValue = &cliKey;
|
|
xResult = ( BaseType_t ) pCtx->pxP11FunctionList->C_GetAttributeValue(
|
|
pCtx->xP11Session, pCtx->xP11PrivateKey, &xTemplate, 1 );
|
|
}
|
|
|
|
/* Get the key size. */
|
|
if( 0 == xResult )
|
|
{
|
|
xTemplate.type = CKA_MODULUS_BITS;
|
|
xTemplate.ulValueLen = sizeof( pCtx->ulP11ModulusBytes );
|
|
xTemplate.pValue = &pCtx->ulP11ModulusBytes;
|
|
xResult = ( BaseType_t ) pCtx->pxP11FunctionList->C_GetAttributeValue(
|
|
pCtx->xP11Session, pCtx->xP11PrivateKey, &xTemplate, 1 );
|
|
}
|
|
|
|
if( 0 == xResult )
|
|
{
|
|
pCtx->ulP11ModulusBytes /= 8;
|
|
|
|
/* Enumerate the first client certificate. */
|
|
xTemplate.type = CKA_CLASS;
|
|
xTemplate.ulValueLen = sizeof( CKA_CLASS );
|
|
xTemplate.pValue = &xObjClass;
|
|
xObjClass = CKO_CERTIFICATE;
|
|
xResult = ( BaseType_t ) pCtx->pxP11FunctionList->C_FindObjectsInit( pCtx->xP11Session, &xTemplate, 1 );
|
|
}
|
|
|
|
if( 0 == xResult )
|
|
{
|
|
xResult = ( BaseType_t ) pCtx->pxP11FunctionList->C_FindObjects( pCtx->xP11Session, &xCertObj, 1, &ulCount );
|
|
}
|
|
|
|
if( 0 == xResult )
|
|
{
|
|
xResult = ( BaseType_t ) pCtx->pxP11FunctionList->C_FindObjectsFinal( pCtx->xP11Session );
|
|
}
|
|
|
|
if( 0 == xResult )
|
|
{
|
|
/* Query the certificate size. */
|
|
xTemplate.type = CKA_VALUE;
|
|
xTemplate.ulValueLen = 0;
|
|
xTemplate.pValue = NULL;
|
|
xResult = ( BaseType_t ) pCtx->pxP11FunctionList->C_GetAttributeValue( pCtx->xP11Session, xCertObj, &xTemplate, 1 );
|
|
}
|
|
|
|
if( 0 == xResult )
|
|
{
|
|
/* Create a buffer for the certificate. */
|
|
pucCertificate = ( CK_BYTE_PTR ) pvPortMalloc( xTemplate.ulValueLen ); /*lint !e9079 Allow casting void* to other types. */
|
|
|
|
if( NULL == pucCertificate )
|
|
{
|
|
xResult = ( BaseType_t ) CKR_HOST_MEMORY;
|
|
}
|
|
}
|
|
|
|
if( 0 == xResult )
|
|
{
|
|
/* Export the certificate. */
|
|
xTemplate.pValue = pucCertificate;
|
|
xResult = ( BaseType_t ) pCtx->pxP11FunctionList->C_GetAttributeValue(
|
|
pCtx->xP11Session, xCertObj, &xTemplate, 1 );
|
|
}
|
|
|
|
/* Decode the client certificate. */
|
|
if( 0 == xResult )
|
|
{
|
|
xResult = wolfSSL_CTX_use_certificate_buffer(pCtx->ctx,
|
|
(const byte*)pucCertificate, xTemplate.ulValueLen,
|
|
WOLFSSL_FILETYPE_ASN1);
|
|
if (xResult == WOLFSSL_SUCCESS)
|
|
xResult = 0;
|
|
|
|
/* Load certificate private key */
|
|
xResult = wolfSSL_CTX_use_PrivateKey_buffer(pCtx->ctx,
|
|
(const byte*)cliKey.der, cliKey.derLen,
|
|
WOLFSSL_FILETYPE_ASN1);
|
|
if (xResult == WOLFSSL_SUCCESS)
|
|
xResult = 0;
|
|
}
|
|
|
|
if( NULL != pucCertificate )
|
|
{
|
|
vPortFree( pucCertificate );
|
|
}
|
|
|
|
return xResult;
|
|
}
|
|
|
|
/*
|
|
* Interface routines.
|
|
*/
|
|
|
|
BaseType_t TLS_Init( void ** ppvContext,
|
|
TLSParams_t * pxParams )
|
|
{
|
|
BaseType_t xResult = 0;
|
|
TLSContext_t * pCtx = NULL;
|
|
|
|
/* Allocate an internal context. */
|
|
pCtx = ( TLSContext_t * ) pvPortMalloc( sizeof( TLSContext_t ) ); /*lint !e9087 !e9079 Allow casting void* to other types. */
|
|
|
|
if( NULL != pCtx )
|
|
{
|
|
memset( pCtx, 0, sizeof( TLSContext_t ) );
|
|
*ppvContext = pCtx;
|
|
|
|
/* Initialize the context. */
|
|
pCtx->pcDestination = pxParams->pcDestination;
|
|
pCtx->pcServerCertificate = pxParams->pcServerCertificate;
|
|
pCtx->ulServerCertificateLength = pxParams->ulServerCertificateLength;
|
|
pCtx->ppcAlpnProtocols = pxParams->ppcAlpnProtocols;
|
|
pCtx->ulAlpnProtocolsCount = pxParams->ulAlpnProtocolsCount;
|
|
pCtx->pxNetworkRecv = pxParams->pxNetworkRecv;
|
|
pCtx->pxNetworkSend = pxParams->pxNetworkSend;
|
|
pCtx->pvCallerContext = pxParams->pvCallerContext;
|
|
|
|
wolfSSL_Init();
|
|
}
|
|
else
|
|
{
|
|
xResult = ( BaseType_t ) CKR_HOST_MEMORY;
|
|
}
|
|
|
|
return xResult;
|
|
}
|
|
|
|
/*-----------------------------------------------------------*/
|
|
|
|
BaseType_t TLS_Connect( void * pvContext )
|
|
{
|
|
BaseType_t xResult = pdFREERTOS_ERRNO_NONE;
|
|
TLSContext_t * pCtx = ( TLSContext_t * ) pvContext; /*lint !e9087 !e9079 Allow casting void* to other types. */
|
|
|
|
/* Ensure that the FreeRTOS heap is used. */
|
|
CRYPTO_ConfigureHeap();
|
|
|
|
/* create wolf context (factory for generating wolfSSL connection objects) */
|
|
pCtx->ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method());
|
|
if (pCtx->ctx == NULL) {
|
|
xResult = pdFREERTOS_ERRNO_ENOMEM;
|
|
}
|
|
|
|
/* load certificate */
|
|
if ( NULL != pCtx->pcServerCertificate )
|
|
{
|
|
xResult = wolfSSL_CTX_load_verify_buffer(pCtx->ctx,
|
|
(const byte*)pCtx->pcServerCertificate,
|
|
pCtx->ulServerCertificateLength, WOLFSSL_FILETYPE_PEM);
|
|
}
|
|
else
|
|
{
|
|
xResult = wolfSSL_CTX_load_verify_buffer(pCtx->ctx,
|
|
(const byte*)tlsVERISIGN_ROOT_CERTIFICATE_PEM,
|
|
tlsVERISIGN_ROOT_CERTIFICATE_LENGTH,
|
|
WOLFSSL_FILETYPE_PEM);
|
|
|
|
if( xResult == WOLFSSL_SUCCESS)
|
|
{
|
|
xResult = wolfSSL_CTX_load_verify_buffer(pCtx->ctx,
|
|
(const byte*)tlsATS1_ROOT_CERTIFICATE_PEM,
|
|
tlsATS1_ROOT_CERTIFICATE_LENGTH,
|
|
WOLFSSL_FILETYPE_PEM);
|
|
}
|
|
if (xResult == WOLFSSL_SUCCESS)
|
|
xResult = 0;
|
|
}
|
|
|
|
if( 0 == xResult )
|
|
{
|
|
wolfSSL_CTX_set_verify(pCtx->ctx, WOLFSSL_VERIFY_PEER,
|
|
prvCheckCertificate);
|
|
|
|
/* Setup the client credential. */
|
|
xResult = prvInitializeClientCredential( pCtx );
|
|
}
|
|
|
|
/* Set the hostname, if requested. */
|
|
if( ( 0 == xResult ) && ( NULL != pCtx->pcDestination ) )
|
|
{
|
|
#ifdef HAVE_SNI
|
|
if (wolfSSL_CTX_UseSNI(pCtx->ctx, 0, pCtx->pcDestination,
|
|
(word16)XSTRLEN(pCtx->pcDestination)) != WOLFSSL_SUCCESS) {
|
|
xResult = pdFREERTOS_ERRNO_ENOPROTOOPT;
|
|
#endif
|
|
}
|
|
|
|
|
|
/* create connection object */
|
|
if( 0 == xResult )
|
|
{
|
|
wolfSSL_CTX_SetIORecv(pCtx->ctx, prvNetworkRecv);
|
|
wolfSSL_CTX_SetIOSend(pCtx->ctx, prvNetworkSend);
|
|
|
|
pCtx->ssl = wolfSSL_new(pCtx->ctx);
|
|
if (pCtx->ssl == NULL) {
|
|
xResult = pdFREERTOS_ERRNO_ENOMEM;
|
|
}
|
|
}
|
|
|
|
if( 0 == xResult && NULL != pCtx->ppcAlpnProtocols )
|
|
{
|
|
/* Include an application protocol list in the TLS ClientHello
|
|
* message. */
|
|
#ifdef HAVE_ALPN
|
|
size_t cur_len, tot_len;
|
|
const char **p;
|
|
tot_len = 0;
|
|
for( p = protos; *p != NULL; p++ ) {
|
|
cur_len = strlen( *p );
|
|
tot_len += cur_len;
|
|
|
|
if (cur_len > 0 && cur_len <= 255 && tot_len < 65535) {
|
|
wolfSSL_UseALPN(pCtx->ssl, *p, (word32)cur_len, WOLFSSL_ALPN_CONTINUE_ON_MISMATCH);
|
|
}
|
|
else {
|
|
xResult = pdFREERTOS_ERRNO_EINVAL;
|
|
break;
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
|
|
/* Set the socket callbacks. */
|
|
if( 0 == xResult )
|
|
{
|
|
/* Setup the IO callbacks */
|
|
wolfSSL_SetIOReadCtx( pCtx->ssl, (void*)pCtx);
|
|
wolfSSL_SetIOWriteCtx(pCtx->ssl, (void*)pCtx);
|
|
|
|
/* Negotiate. */
|
|
while( WOLFSSL_SUCCESS != ( xResult = wolfSSL_connect(pCtx->ssl) ) )
|
|
{
|
|
xResult = wolfSSL_get_error(pCtx->ssl, 0);
|
|
|
|
if( ( WOLFSSL_ERROR_WANT_READ != xResult ) &&
|
|
( WOLFSSL_ERROR_WANT_WRITE != xResult ) )
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
if (xResult == WOLFSSL_SUCCESS)
|
|
xResult = 0;
|
|
}
|
|
|
|
return xResult;
|
|
}
|
|
|
|
/*-----------------------------------------------------------*/
|
|
|
|
BaseType_t TLS_Recv( void * pvContext,
|
|
unsigned char * pucReadBuffer,
|
|
size_t xReadLength )
|
|
{
|
|
BaseType_t xResult = 0;
|
|
TLSContext_t * pCtx = ( TLSContext_t * ) pvContext; /*lint !e9087 !e9079 Allow casting void* to other types. */
|
|
size_t xRead = 0;
|
|
|
|
if( NULL != pCtx )
|
|
{
|
|
while( xRead < xReadLength )
|
|
{
|
|
xResult = wolfSSL_read( pCtx->ssl,
|
|
pucReadBuffer + xRead,
|
|
xReadLength - xRead );
|
|
|
|
if( 0 < xResult )
|
|
{
|
|
/* Got data, so update the tally and keep looping. */
|
|
xRead += ( size_t ) xResult;
|
|
}
|
|
else
|
|
{
|
|
if( ( 0 == xResult ) || ( WOLFSSL_ERROR_WANT_READ != xResult ) )
|
|
{
|
|
/* No data and no error or call read again, if indicated, otherwise return error. */
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if( 0 <= xResult )
|
|
{
|
|
xResult = ( BaseType_t ) xRead;
|
|
}
|
|
|
|
return xResult;
|
|
}
|
|
|
|
/*-----------------------------------------------------------*/
|
|
|
|
BaseType_t TLS_Send( void * pvContext,
|
|
const unsigned char * pucMsg,
|
|
size_t xMsgLength )
|
|
{
|
|
BaseType_t xResult = 0;
|
|
TLSContext_t * pCtx = ( TLSContext_t * ) pvContext; /*lint !e9087 !e9079 Allow casting void* to other types. */
|
|
size_t xWritten = 0;
|
|
|
|
if( NULL != pCtx )
|
|
{
|
|
while( xWritten < xMsgLength )
|
|
{
|
|
xResult = wolfSSL_write( pCtx->ssl,
|
|
pucMsg + xWritten,
|
|
xMsgLength - xWritten );
|
|
|
|
if( 0 < xResult )
|
|
{
|
|
/* Sent data, so update the tally and keep looping. */
|
|
xWritten += ( size_t ) xResult;
|
|
}
|
|
else
|
|
{
|
|
if( ( 0 == xResult ) || ( WOLFSSL_ERROR_WANT_WRITE != xResult ) )
|
|
{
|
|
/* No data and no error or call read again, if indicated, otherwise return error. */
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if( 0 <= xResult )
|
|
{
|
|
xResult = ( BaseType_t ) xWritten;
|
|
}
|
|
|
|
return xResult;
|
|
}
|
|
|
|
/*-----------------------------------------------------------*/
|
|
|
|
void TLS_Cleanup( void * pvContext )
|
|
{
|
|
TLSContext_t * pCtx = ( TLSContext_t * ) pvContext; /*lint !e9087 !e9079 Allow casting void* to other types. */
|
|
|
|
if( NULL != pCtx )
|
|
{
|
|
/* Cleanup wolfSSL. */
|
|
wolfSSL_shutdown( pCtx->ssl );
|
|
wolfSSL_free( pCtx->ssl );
|
|
wolfSSL_CTX_free( pCtx->ctx );
|
|
|
|
/* Cleanup PKCS#11. */
|
|
if( ( NULL != pCtx->pxP11FunctionList ) &&
|
|
( NULL != pCtx->pxP11FunctionList->C_CloseSession ) )
|
|
{
|
|
pCtx->pxP11FunctionList->C_CloseSession( pCtx->xP11Session ); /*lint !e534 This function always return CKR_OK. */
|
|
pCtx->pxP11FunctionList->C_Finalize( NULL ); /*lint !e534 This function always return CKR_OK. */
|
|
}
|
|
|
|
wolfSSL_Cleanup();
|
|
|
|
/* Free memory. */
|
|
vPortFree( pCtx );
|
|
}
|
|
}
|
|
|
|
#endif /* WOLF_AWSTLS */
|