1 /* 2 * FreeRTOS V202212.00 3 * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 * this software and associated documentation files (the "Software"), to deal in 7 * the Software without restriction, including without limitation the rights to 8 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 * the Software, and to permit persons to whom the Software is furnished to do so, 10 * subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice shall be included in all 13 * copies or substantial portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 * 22 * https://www.FreeRTOS.org 23 * https://github.com/FreeRTOS 24 * 25 */ 26 27 /** 28 * @file transport_mbedtls_pkcs11.h 29 * @brief TLS transport interface header. 30 * @note This file is derived from the tls_freertos.h header file found in the mqtt 31 * section of IoT Libraries source code. The file has been modified to support using 32 * PKCS #11 when using TLS. 33 */ 34 35 #ifndef TRANSPORT_MBEDTLS_PKCS11 36 #define TRANSPORT_MBEDTLS_PKCS11 37 38 #define MBEDTLS_ALLOW_PRIVATE_ACCESS 39 40 #if !defined( MBEDTLS_CONFIG_FILE ) 41 #include "mbedtls/mbedtls_config.h" 42 #else 43 #include MBEDTLS_CONFIG_FILE 44 #endif 45 46 #include "mbedtls/private_access.h" 47 48 /* TCP Sockets Wrapper include.*/ 49 #include "tcp_sockets_wrapper.h" 50 51 /* Transport interface include. */ 52 #include "transport_interface.h" 53 54 /* mbed TLS includes. */ 55 #include "mbedtls/build_info.h" 56 #include "mbedtls/ctr_drbg.h" 57 #include "mbedtls/entropy.h" 58 #include "mbedtls/ssl.h" 59 #include "mbedtls/threading.h" 60 #include "mbedtls/x509.h" 61 #include "mbedtls/pk.h" 62 #include "mbedtls/error.h" 63 64 #include "pk_wrap.h" 65 66 /* PKCS #11 includes. */ 67 #include "core_pkcs11.h" 68 69 /** 70 * @brief Secured connection context. 71 */ 72 typedef struct SSLContext 73 { 74 mbedtls_ssl_config config; /**< @brief SSL connection configuration. */ 75 mbedtls_ssl_context context; /**< @brief SSL connection context */ 76 mbedtls_x509_crt_profile certProfile; /**< @brief Certificate security profile for this connection. */ 77 mbedtls_x509_crt rootCa; /**< @brief Root CA certificate context. */ 78 mbedtls_x509_crt clientCert; /**< @brief Client certificate context. */ 79 mbedtls_pk_context privKey; /**< @brief Client private key context. */ 80 mbedtls_pk_info_t privKeyInfo; /**< @brief Client private key info. */ 81 82 /* PKCS#11. */ 83 CK_FUNCTION_LIST_PTR pxP11FunctionList; 84 CK_SESSION_HANDLE xP11Session; 85 CK_OBJECT_HANDLE xP11PrivateKey; 86 } SSLContext_t; 87 88 /** 89 * @brief Definition of the network context for the transport interface 90 * implementation that uses mbedTLS and FreeRTOS+TLS sockets. 91 */ 92 typedef struct TlsTransportParams 93 { 94 Socket_t tcpSocket; 95 SSLContext_t sslContext; 96 } TlsTransportParams_t; 97 98 /** 99 * @brief Contains the credentials necessary for tls connection setup. 100 */ 101 typedef struct NetworkCredentials 102 { 103 /** 104 * @brief To use ALPN, set this to a NULL-terminated list of supported 105 * protocols in decreasing order of preference. 106 * 107 * See [this link] 108 * (https://aws.amazon.com/blogs/iot/mqtt-with-tls-client-authentication-on-port-443-why-it-is-useful-and-how-it-works/) 109 * for more information. 110 */ 111 const char ** pAlpnProtos; 112 113 /** 114 * @brief Disable server name indication (SNI) for a TLS session. 115 */ 116 BaseType_t disableSni; 117 118 const unsigned char * pRootCa; /**< @brief String representing a trusted server root certificate. */ 119 size_t rootCaSize; /**< @brief Size associated with #NetworkCredentials.pRootCa. */ 120 const unsigned char * pUserName; /**< @brief username for MQTT. */ 121 size_t userNameSize; /**< @brief Size associated with #NetworkCredentials.pUserName. */ 122 const unsigned char * pPassword; /**< @brief String representing the password for MQTT. */ 123 size_t passwordSize; /**< @brief Size associated with #NetworkCredentials.pPassword. */ 124 const char * pClientCertLabel; /**< @brief PKCS #11 label string of the client certificate. */ 125 const char * pPrivateKeyLabel; /**< @brief PKCS #11 label for the private key. */ 126 } NetworkCredentials_t; 127 128 /** 129 * @brief TLS Connect / Disconnect return status. 130 */ 131 typedef enum TlsTransportStatus 132 { 133 TLS_TRANSPORT_SUCCESS = 0, /**< Function successfully completed. */ 134 TLS_TRANSPORT_INVALID_PARAMETER, /**< At least one parameter was invalid. */ 135 TLS_TRANSPORT_INSUFFICIENT_MEMORY, /**< Insufficient memory required to establish connection. */ 136 TLS_TRANSPORT_INVALID_CREDENTIALS, /**< Provided credentials were invalid. */ 137 TLS_TRANSPORT_HANDSHAKE_FAILED, /**< Performing TLS handshake with server failed. */ 138 TLS_TRANSPORT_INTERNAL_ERROR, /**< A call to a system API resulted in an internal error. */ 139 TLS_TRANSPORT_CONNECT_FAILURE /**< Initial connection to the server failed. */ 140 } TlsTransportStatus_t; 141 142 /** 143 * @brief Create a TLS connection with FreeRTOS sockets. 144 * 145 * @param[out] pNetworkContext Pointer to a network context to contain the 146 * initialized socket handle. 147 * @param[in] pHostName The hostname of the remote endpoint. 148 * @param[in] port The destination port. 149 * @param[in] pNetworkCredentials Credentials for the TLS connection. 150 * @param[in] receiveTimeoutMs Receive socket timeout. 151 * @param[in] sendTimeoutMs Send socket timeout. 152 * 153 * @return #TLS_TRANSPORT_SUCCESS, #TLS_TRANSPORT_INSUFFICIENT_MEMORY, #TLS_TRANSPORT_INVALID_CREDENTIALS, 154 * #TLS_TRANSPORT_HANDSHAKE_FAILED, #TLS_TRANSPORT_INTERNAL_ERROR, or #TLS_TRANSPORT_CONNECT_FAILURE. 155 */ 156 TlsTransportStatus_t TLS_FreeRTOS_Connect( NetworkContext_t * pNetworkContext, 157 const char * pHostName, 158 uint16_t port, 159 const NetworkCredentials_t * pNetworkCredentials, 160 uint32_t receiveTimeoutMs, 161 uint32_t sendTimeoutMs ); 162 163 /** 164 * @brief Gracefully disconnect an established TLS connection. 165 * 166 * @param[in] pNetworkContext Network context. 167 */ 168 void TLS_FreeRTOS_Disconnect( NetworkContext_t * pNetworkContext ); 169 170 /** 171 * @brief Receives data from an established TLS connection. 172 * 173 * This is the TLS version of the transport interface's 174 * #TransportRecv_t function. 175 * 176 * @param[in] pNetworkContext The Network context. 177 * @param[out] pBuffer Buffer to receive bytes into. 178 * @param[in] bytesToRecv Number of bytes to receive from the network. 179 * 180 * @return Number of bytes (> 0) received if successful; 181 * 0 if the socket times out without reading any bytes; 182 * negative value on error. 183 */ 184 int32_t TLS_FreeRTOS_recv( NetworkContext_t * pNetworkContext, 185 void * pBuffer, 186 size_t bytesToRecv ); 187 188 /** 189 * @brief Sends data over an established TLS connection. 190 * 191 * @note This is the TLS version of the transport interface's 192 * #TransportSend_t function. 193 * 194 * @param[in] pNetworkContext The network context. 195 * @param[in] pBuffer Buffer containing the bytes to send. 196 * @param[in] bytesToSend Number of bytes to send from the buffer. 197 * 198 * @return Number of bytes (> 0) sent on success; 199 * 0 if the socket times out without sending any bytes; 200 * else a negative value to represent error. 201 */ 202 int32_t TLS_FreeRTOS_send( NetworkContext_t * pNetworkContext, 203 const void * pBuffer, 204 size_t bytesToSend ); 205 206 207 #ifdef MBEDTLS_DEBUG_C 208 209 /** 210 * @brief Write an MBedTLS Debug message to the LogDebug() function 211 * 212 * @param[in] sslContext Pointer of the SSL Context that is being used 213 * @param[in] level The severity level of the debug message from MBedTLS 214 * @param[in] file Name of the file that the debug message is from 215 * @param[in] line The line number that the debug message is from 216 * @param[in] str The full string debug message from MBedTLS 217 * 218 * @return void 219 */ 220 void mbedtls_string_printf( void * sslContext, 221 int level, 222 const char * file, 223 int line, 224 const char * str ); 225 #endif /* MBEDTLS_DEBUG_C */ 226 227 #endif /* ifndef TRANSPORT_MBEDTLS_PKCS11 */ 228