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