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