]> git.sur5r.net Git - freertos/blob - FreeRTOS-Plus/Demo/FreeRTOS_Plus_CyaSSL_Windows_Simulator/SecureTCPServerTask.c
Update WolfSSL library to the latest version.
[freertos] / FreeRTOS-Plus / Demo / FreeRTOS_Plus_CyaSSL_Windows_Simulator / SecureTCPServerTask.c
1 /*\r
2     FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
3     All rights reserved\r
4 \r
5     VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
6 \r
7     This file is part of the FreeRTOS distribution.\r
8 \r
9     FreeRTOS is free software; you can redistribute it and/or modify it under\r
10     the terms of the GNU General Public License (version 2) as published by the\r
11     Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.\r
12 \r
13     ***************************************************************************\r
14     >>!   NOTE: The modification to the GPL is included to allow you to     !<<\r
15     >>!   distribute a combined work that includes FreeRTOS without being   !<<\r
16     >>!   obliged to provide the source code for proprietary components     !<<\r
17     >>!   outside of the FreeRTOS kernel.                                   !<<\r
18     ***************************************************************************\r
19 \r
20     FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
21     WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
22     FOR A PARTICULAR PURPOSE.  Full license text is available on the following\r
23     link: http://www.freertos.org/a00114.html\r
24 \r
25     ***************************************************************************\r
26      *                                                                       *\r
27      *    FreeRTOS provides completely free yet professionally developed,    *\r
28      *    robust, strictly quality controlled, supported, and cross          *\r
29      *    platform software that is more than just the market leader, it     *\r
30      *    is the industry's de facto standard.                               *\r
31      *                                                                       *\r
32      *    Help yourself get started quickly while simultaneously helping     *\r
33      *    to support the FreeRTOS project by purchasing a FreeRTOS           *\r
34      *    tutorial book, reference manual, or both:                          *\r
35      *    http://www.FreeRTOS.org/Documentation                              *\r
36      *                                                                       *\r
37     ***************************************************************************\r
38 \r
39     http://www.FreeRTOS.org/FAQHelp.html - Having a problem?  Start by reading\r
40     the FAQ page "My application does not run, what could be wrong?".  Have you\r
41     defined configASSERT()?\r
42 \r
43     http://www.FreeRTOS.org/support - In return for receiving this top quality\r
44     embedded software for free we request you assist our global community by\r
45     participating in the support forum.\r
46 \r
47     http://www.FreeRTOS.org/training - Investing in training allows your team to\r
48     be as productive as possible as early as possible.  Now you can receive\r
49     FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers\r
50     Ltd, and the world's leading authority on the world's leading RTOS.\r
51 \r
52     http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
53     including FreeRTOS+Trace - an indispensable productivity tool, a DOS\r
54     compatible FAT file system, and our tiny thread aware UDP/IP stack.\r
55 \r
56     http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.\r
57     Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.\r
58 \r
59     http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High\r
60     Integrity Systems ltd. to sell under the OpenRTOS brand.  Low cost OpenRTOS\r
61     licenses offer ticketed support, indemnification and commercial middleware.\r
62 \r
63     http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
64     engineered and independently SIL3 certified version for use in safety and\r
65     mission critical applications that require provable dependability.\r
66 \r
67     1 tab == 4 spaces!\r
68 */\r
69 \r
70 #pragma comment( lib, "ws2_32.lib" )\r
71 \r
72 /* Win32 includes. */\r
73 #include <WinSock2.h>\r
74 \r
75 /* CyaSSL includes. */\r
76 #include "cyassl/ssl.h"\r
77 \r
78 /* Standard includes. */\r
79 #include <stdint.h>\r
80 #include <stdio.h>\r
81 \r
82 /* FreeRTOS includes. */\r
83 #include "FreeRTOS.h"\r
84 #include "task.h"\r
85 \r
86 /* This application is using the FreeRTOS Windows simulator, which uses the\r
87 FreeRTOS scheduler to schedule FreeRTOS task within the Windows environment.\r
88 The Windows envrionment must not be allowed to block any Windows threads that\r
89 are running FreeRTOS tasks, unless the FreeRTOS task is running at the FreeRTOS\r
90 idle priority.  For simplicity, this demo uses the Windows TCP/IP stack, the\r
91 API for which can cause Windows threads to block.  Therefore, any FreeRTOS task\r
92 that makes calls to the Windows TCP/IP stack must be assigned the idle prioity.\r
93 Note this is only a restriction of the simulated Windows environment - real\r
94 FreeRTOS ports do not have this restriction. */\r
95 #define sstSECURE_CLIENT_TASK_PRIORITY          ( tskIDLE_PRIORITY )\r
96 \r
97 /*-----------------------------------------------------------*/\r
98 \r
99 /*\r
100  * Open, configures and binds the server's TCP socket.\r
101  */\r
102 static SOCKET prvOpenServerSocket( void );\r
103 \r
104 /* \r
105  * Prepare the CyaSSL library for use.\r
106  */\r
107 static void prvInitialiseCyaSSL( void );\r
108 \r
109 /*\r
110  * The task that implements the client side of the connection.\r
111  */\r
112 extern void vSecureTCPClientTask( void *pvParameters );\r
113 \r
114 /*-----------------------------------------------------------*/\r
115 \r
116 /* The CyaSSL context for the server. */\r
117 static CYASSL_CTX* xCyaSSL_ServerContext = NULL;\r
118 \r
119 /*-----------------------------------------------------------*/\r
120 \r
121 /* See the comments at the top of main.c. */\r
122 void vSecureTCPServerTask( void *pvParameters )\r
123 {\r
124 BaseType_t xReturned;\r
125 long lBytes;\r
126 uint8_t cReceivedString[ 60 ];\r
127 struct sockaddr_in xClient;\r
128 int xClientAddressLength = sizeof( struct sockaddr_in );\r
129 SOCKET xListeningSocket, xConnectedSocket;\r
130 CYASSL* xCyaSSL_Object; /* Only one connection is accepted at a time, so only one object is needed at a time. */\r
131 \r
132         /* Just to prevent compiler warnings. */\r
133         ( void ) pvParameters;\r
134 \r
135         /* Perform the initialisation necessary before CyaSSL can be used. */\r
136         prvInitialiseCyaSSL();\r
137         configASSERT( xCyaSSL_ServerContext );\r
138 \r
139         /* Attempt to open the socket. */\r
140         xListeningSocket = prvOpenServerSocket();\r
141 \r
142         /* Now the server socket has been created and the CyaSSL library has been\r
143         initialised, the task that implements the client side can be created. */\r
144         xTaskCreate( vSecureTCPClientTask, "Client", configMINIMAL_STACK_SIZE, NULL, sstSECURE_CLIENT_TASK_PRIORITY, NULL );\r
145 \r
146         if( xListeningSocket != INVALID_SOCKET )\r
147         {\r
148                 for( ;; )\r
149                 {\r
150                         /* Wait until the client connects. */\r
151                         printf( "Waiting for new connection\r\n" );\r
152                         xConnectedSocket = accept( xListeningSocket, ( struct sockaddr * ) &xClient, &xClientAddressLength );\r
153 \r
154                         if( xConnectedSocket != INVALID_SOCKET )\r
155                         {\r
156                                 printf( "Connection established\r\n" );\r
157 \r
158                                 /* A connection has been accepted by the server.  Create a \r
159                                 CyaSSL object for use with the newly connected socket. */\r
160                                 xCyaSSL_Object = NULL;\r
161                                 xCyaSSL_Object = CyaSSL_new( xCyaSSL_ServerContext );\r
162     \r
163                                 if( xCyaSSL_Object != NULL )\r
164                                 {\r
165                                         /* Associate the created CyaSSL object with the connected \r
166                                         socket. */\r
167                                         xReturned = CyaSSL_set_fd( xCyaSSL_Object, xConnectedSocket );\r
168                                         configASSERT( xReturned == SSL_SUCCESS );\r
169 \r
170                                         do\r
171                                         {\r
172                                                 /* The next line is the secure equivalent to the \r
173                                                 standard sockets call:\r
174                                                 lBytes = recv( xConnectedSocket, cReceivedString, 50, 0 ); */\r
175                                                 lBytes = CyaSSL_read( xCyaSSL_Object, cReceivedString, sizeof( cReceivedString ) );\r
176                                                 \r
177                                                 /* Print the received characters. */\r
178                                                 if( lBytes > 0 )\r
179                                                 {\r
180                                                         printf( "Received by the secure server: %s\r\n", cReceivedString );\r
181                                                 }\r
182 \r
183                                         } while ( lBytes > 0 );\r
184 \r
185                                         /* The connection was closed, close the socket and free the\r
186                                         CyaSSL object. */\r
187                                         closesocket( xConnectedSocket );                                        \r
188                                         CyaSSL_free( xCyaSSL_Object );\r
189                                         printf( "Connection closed, back to start\r\n\r\n" );\r
190                                 }                                                               \r
191                         }\r
192                 } \r
193         }\r
194         else\r
195         {\r
196                 /* The socket could not be opened. */\r
197                 vTaskDelete( NULL );\r
198         }\r
199 }\r
200 /*-----------------------------------------------------------*/\r
201 \r
202 static SOCKET prvOpenServerSocket( void )\r
203 {\r
204 WSADATA xWSAData;\r
205 WORD wVersionRequested;\r
206 struct sockaddr_in xConnection;\r
207 SOCKET xSocket = INVALID_SOCKET;\r
208 \r
209         wVersionRequested = MAKEWORD( 2, 2 );\r
210 \r
211         /* Prepare to use WinSock. */\r
212         if( WSAStartup( wVersionRequested, &xWSAData ) != 0 )\r
213         {\r
214                 fprintf( stderr, "Could not open Windows connection.\n" );\r
215         }\r
216         else\r
217         {\r
218                 xSocket = socket( AF_INET, SOCK_STREAM, 0 );\r
219                 if( xSocket == INVALID_SOCKET)\r
220                 {\r
221                         fprintf( stderr, "Could not create socket.\n" );\r
222                         WSACleanup();\r
223                 }\r
224                 else\r
225                 {\r
226                         /* Zero out the server structure. */\r
227                         memset( ( void * ) &xConnection, 0x00, sizeof( struct sockaddr_in ) );\r
228 \r
229                         xConnection.sin_family = AF_INET;\r
230                         xConnection.sin_addr.s_addr = inet_addr("127.0.0.1");\r
231                         xConnection.sin_port = htons( configTCP_PORT_NUMBER );\r
232 \r
233                         /* Bind the address to the socket. */\r
234                         if( bind( xSocket, ( struct sockaddr * ) &xConnection, sizeof( struct sockaddr_in ) ) == -1 )\r
235                         {\r
236                                 fprintf( stderr, "Could not socket to port %d.\n", configTCP_PORT_NUMBER );\r
237                                 closesocket( xSocket );\r
238                                 xSocket = INVALID_SOCKET;\r
239                                 WSACleanup();\r
240                         }\r
241 \r
242                         if( listen( xSocket, 20 ) != 0 )\r
243                         {\r
244                                 closesocket( xSocket );\r
245                                 xSocket = INVALID_SOCKET;\r
246                                 WSACleanup();\r
247                         }\r
248                 }\r
249         }\r
250 \r
251         return xSocket;\r
252 }\r
253 /*-----------------------------------------------------------*/\r
254 \r
255 static void prvInitialiseCyaSSL( void )\r
256 {\r
257 int32_t iReturn;\r
258 \r
259         #ifdef DEBUG_CYASSL\r
260         {\r
261                 CyaSSL_Debugging_ON();\r
262         }\r
263         #endif\r
264 \r
265     /* Initialise CyaSSL.  This must be done before any other CyaSSL functions\r
266     are called. */\r
267     CyaSSL_Init();\r
268 \r
269     /* Attempt to create a context that uses the TLS V1 server protocol. */\r
270     xCyaSSL_ServerContext = CyaSSL_CTX_new( CyaTLSv1_server_method() );\r
271 \r
272     if( xCyaSSL_ServerContext != NULL )\r
273     {\r
274         /* Load the CA certificate.  Real applications should ensure that\r
275         CyaSSL_CTX_load_verify_locations() returns SSL_SUCCESS before \r
276                 proceeding. */\r
277         iReturn = CyaSSL_CTX_load_verify_locations( xCyaSSL_ServerContext, "ca-cert.pem", 0 );\r
278                 configASSERT( iReturn == SSL_SUCCESS );\r
279 \r
280                 iReturn = CyaSSL_CTX_use_certificate_file( xCyaSSL_ServerContext, "server-cert.pem", SSL_FILETYPE_PEM );\r
281                 configASSERT( iReturn == SSL_SUCCESS );\r
282 \r
283                 iReturn = CyaSSL_CTX_use_PrivateKey_file( xCyaSSL_ServerContext, "server-key.pem", SSL_FILETYPE_PEM );\r
284                 configASSERT( iReturn == SSL_SUCCESS );\r
285     }\r
286 }\r
287 \r
288 \r