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