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 tls_freertos.h
29  * @brief TLS transport interface header.
30  */
31 
32 #ifndef USING_MBEDTLS
33 #define USING_MBEDTLS
34 
35 /* MBed TLS includes. */
36 #if !defined( MBEDTLS_CONFIG_FILE )
37     #include "mbedtls/mbedtls_config.h"
38 #else
39     #include MBEDTLS_CONFIG_FILE
40 #endif
41 
42 #include "mbedtls/build_info.h"
43 #include "mbedtls/ctr_drbg.h"
44 #include "mbedtls/entropy.h"
45 #include "mbedtls/ssl.h"
46 #include "mbedtls/threading.h"
47 #include "mbedtls/x509.h"
48 #include "mbedtls/error.h"
49 
50 
51 /**************************************************/
52 /******* DO NOT CHANGE the following order ********/
53 /**************************************************/
54 
55 /* Logging related header files are required to be included in the following order:
56  * 1. Include the header file "logging_levels.h".
57  * 2. Define LIBRARY_LOG_NAME and  LIBRARY_LOG_LEVEL.
58  * 3. Include the header file "logging_stack.h".
59  */
60 
61 /* Include header that defines log levels. */
62 #include "logging_levels.h"
63 
64 /* Logging configuration for the Sockets. */
65 #ifndef LIBRARY_LOG_NAME
66     #define LIBRARY_LOG_NAME     "TlsTransport"
67 #endif
68 #ifndef LIBRARY_LOG_LEVEL
69     #define LIBRARY_LOG_LEVEL    LOG_ERROR
70 #endif
71 
72 /** @brief Prototype for the function used to print to console on Windows
73  * simulator of FreeRTOS.
74  *
75  * @note The function prints to the console before the network is connected;
76  * then a UDP port after the network has connected. */
77 extern void vLoggingPrintf( const char * pcFormatString,
78                             ... );
79 
80 /* Map the SdkLog macro to the logging function to enable logging
81  * on Windows simulator. */
82 #ifndef SdkLog
83     #define SdkLog( message )    vLoggingPrintf message
84 #endif
85 
86 #include "logging_stack.h"
87 
88 /************ End of logging configuration ****************/
89 
90 /* TCP Sockets Wrapper include.*/
91 #include "tcp_sockets_wrapper.h"
92 
93 /* Transport interface include. */
94 #include "transport_interface.h"
95 
96 /**
97  * @brief Secured connection context.
98  */
99 typedef struct SSLContext
100 {
101     mbedtls_ssl_config config;               /**< @brief SSL connection configuration. */
102     mbedtls_ssl_context context;             /**< @brief SSL connection context */
103     mbedtls_x509_crt_profile certProfile;    /**< @brief Certificate security profile for this connection. */
104     mbedtls_x509_crt rootCa;                 /**< @brief Root CA certificate context. */
105     mbedtls_x509_crt clientCert;             /**< @brief Client certificate context. */
106     mbedtls_pk_context privKey;              /**< @brief Client private key context. */
107     mbedtls_entropy_context entropyContext;  /**< @brief Entropy context for random number generation. */
108     mbedtls_ctr_drbg_context ctrDrbgContext; /**< @brief CTR DRBG context for random number generation. */
109 } SSLContext_t;
110 
111 /**
112  * @brief Parameters for the network context of the transport interface
113  * implementation that uses mbedTLS and FreeRTOS+TCP sockets.
114  */
115 typedef struct TlsTransportParams
116 {
117     Socket_t tcpSocket;
118     SSLContext_t sslContext;
119 } TlsTransportParams_t;
120 
121 /**
122  * @brief Contains the credentials necessary for tls connection setup.
123  */
124 typedef struct NetworkCredentials
125 {
126     /**
127      * @brief To use ALPN, set this to a NULL-terminated list of supported
128      * protocols in decreasing order of preference.
129      *
130      * See [this link]
131      * (https://aws.amazon.com/blogs/iot/mqtt-with-tls-client-authentication-on-port-443-why-it-is-useful-and-how-it-works/)
132      * for more information.
133      */
134     const char ** pAlpnProtos;
135 
136     /**
137      * @brief Disable server name indication (SNI) for a TLS session.
138      */
139     BaseType_t disableSni;
140 
141     const uint8_t * pRootCa;     /**< @brief String representing a trusted server root certificate. */
142     size_t rootCaSize;           /**< @brief Size associated with #NetworkCredentials.pRootCa. */
143     const uint8_t * pClientCert; /**< @brief String representing the client certificate. */
144     size_t clientCertSize;       /**< @brief Size associated with #NetworkCredentials.pClientCert. */
145     const uint8_t * pPrivateKey; /**< @brief String representing the client certificate's private key. */
146     size_t privateKeySize;       /**< @brief Size associated with #NetworkCredentials.pPrivateKey. */
147 } NetworkCredentials_t;
148 
149 /**
150  * @brief TLS Connect / Disconnect return status.
151  */
152 typedef enum TlsTransportStatus
153 {
154     TLS_TRANSPORT_SUCCESS = 0,         /**< Function successfully completed. */
155     TLS_TRANSPORT_INVALID_PARAMETER,   /**< At least one parameter was invalid. */
156     TLS_TRANSPORT_INSUFFICIENT_MEMORY, /**< Insufficient memory required to establish connection. */
157     TLS_TRANSPORT_INVALID_CREDENTIALS, /**< Provided credentials were invalid. */
158     TLS_TRANSPORT_HANDSHAKE_FAILED,    /**< Performing TLS handshake with server failed. */
159     TLS_TRANSPORT_INTERNAL_ERROR,      /**< A call to a system API resulted in an internal error. */
160     TLS_TRANSPORT_CONNECT_FAILURE      /**< Initial connection to the server failed. */
161 } TlsTransportStatus_t;
162 
163 /**
164  * @brief Create a TLS connection with FreeRTOS sockets.
165  *
166  * @param[out] pNetworkContext Pointer to a network context to contain the
167  * initialized socket handle.
168  * @param[in] pHostName The hostname of the remote endpoint.
169  * @param[in] port The destination port.
170  * @param[in] pNetworkCredentials Credentials for the TLS connection.
171  * @param[in] receiveTimeoutMs Receive socket timeout.
172  * @param[in] sendTimeoutMs Send socket timeout.
173  *
174  * @return #TLS_TRANSPORT_SUCCESS, #TLS_TRANSPORT_INSUFFICIENT_MEMORY, #TLS_TRANSPORT_INVALID_CREDENTIALS,
175  * #TLS_TRANSPORT_HANDSHAKE_FAILED, #TLS_TRANSPORT_INTERNAL_ERROR, or #TLS_TRANSPORT_CONNECT_FAILURE.
176  */
177 TlsTransportStatus_t TLS_FreeRTOS_Connect( NetworkContext_t * pNetworkContext,
178                                            const char * pHostName,
179                                            uint16_t port,
180                                            const NetworkCredentials_t * pNetworkCredentials,
181                                            uint32_t receiveTimeoutMs,
182                                            uint32_t sendTimeoutMs );
183 
184 /**
185  * @brief Gracefully disconnect an established TLS connection.
186  *
187  * @param[in] pNetworkContext Network context.
188  */
189 void TLS_FreeRTOS_Disconnect( NetworkContext_t * pNetworkContext );
190 
191 /**
192  * @brief Receives data from an established TLS connection.
193  *
194  * @note This is the TLS version of the transport interface's
195  * #TransportRecv_t function.
196  *
197  * @param[in] pNetworkContext The Network context.
198  * @param[out] pBuffer Buffer to receive bytes into.
199  * @param[in] bytesToRecv Number of bytes to receive from the network.
200  *
201  * @return Number of bytes (> 0) received if successful;
202  * 0 if the socket times out without reading any bytes;
203  * negative value on error.
204  */
205 int32_t TLS_FreeRTOS_recv( NetworkContext_t * pNetworkContext,
206                            void * pBuffer,
207                            size_t bytesToRecv );
208 
209 /**
210  * @brief Sends data over an established TLS connection.
211  *
212  * @note This is the TLS version of the transport interface's
213  * #TransportSend_t function.
214  *
215  * @param[in] pNetworkContext The network context.
216  * @param[in] pBuffer Buffer containing the bytes to send.
217  * @param[in] bytesToSend Number of bytes to send from the buffer.
218  *
219  * @return Number of bytes (> 0) sent on success;
220  * 0 if the socket times out without sending any bytes;
221  * else a negative value to represent error.
222  */
223 int32_t TLS_FreeRTOS_send( NetworkContext_t * pNetworkContext,
224                            const void * pBuffer,
225                            size_t bytesToSend );
226 
227 
228 #ifdef MBEDTLS_DEBUG_C
229 
230 /**
231  * @brief Write an MBedTLS Debug message to the LogDebug() function
232  *
233  * @param[in] sslContext Pointer of the SSL Context that is being used
234  * @param[in] level The severity level of the debug message from MBedTLS
235  * @param[in] file Name of the file that the debug message is from
236  * @param[in] line The line number that the debug message is from
237  * @param[in] str The full string debug message from MBedTLS
238  *
239  * @return void
240  */
241     void mbedtls_string_printf( void * sslContext,
242                                 int level,
243                                 const char * file,
244                                 int line,
245                                 const char * str );
246 #endif /* MBEDTLS_DEBUG_C */
247 
248 #endif /* ifndef USING_MBEDTLS */
249