2 FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd.
\r
4 VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
\r
6 ***************************************************************************
\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
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
18 ***************************************************************************
\r
20 This file is part of the FreeRTOS distribution.
\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
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
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
38 ***************************************************************************
\r
40 * Having a problem? Start by reading the FAQ "My application does *
\r
41 * not run, what could be wrong?" *
\r
43 * http://www.FreeRTOS.org/FAQHelp.html *
\r
45 ***************************************************************************
\r
47 http://www.FreeRTOS.org - Documentation, books, training, latest versions,
\r
48 license and Real Time Engineers Ltd. contact details.
\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
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
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
65 #pragma comment( lib, "ws2_32.lib" )
\r
67 /* Win32 includes. */
\r
68 #include <WinSock2.h>
\r
70 /* CyaSSL includes. */
\r
71 #include "cyassl/ssl.h"
\r
73 /* Standard includes. */
\r
77 /* FreeRTOS includes. */
\r
78 #include "FreeRTOS.h"
\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
92 /*-----------------------------------------------------------*/
\r
95 * Open, configures and binds the server's TCP socket.
\r
97 static SOCKET prvOpenServerSocket( void );
\r
100 * Prepare the CyaSSL library for use.
\r
102 static void prvInitialiseCyaSSL( void );
\r
105 * The task that implements the client side of the connection.
\r
107 extern void vSecureTCPClientTask( void *pvParameters );
\r
109 /*-----------------------------------------------------------*/
\r
111 /* The CyaSSL context for the server. */
\r
112 static CYASSL_CTX* xCyaSSL_ServerContext = NULL;
\r
114 /*-----------------------------------------------------------*/
\r
116 /* See the comments at the top of main.c. */
\r
117 void vSecureTCPServerTask( void *pvParameters )
\r
119 portBASE_TYPE xReturned;
\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
127 /* Just to prevent compiler warnings. */
\r
128 ( void ) pvParameters;
\r
130 /* Perform the initialisation necessary before CyaSSL can be used. */
\r
131 prvInitialiseCyaSSL();
\r
132 configASSERT( xCyaSSL_ServerContext );
\r
134 /* Attempt to open the socket. */
\r
135 xListeningSocket = prvOpenServerSocket();
\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
141 if( xListeningSocket != INVALID_SOCKET )
\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
149 if( xConnectedSocket != INVALID_SOCKET )
\r
151 printf( "Connection established\r\n" );
\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
158 if( xCyaSSL_Object != NULL )
\r
160 /* Associate the created CyaSSL object with the connected
\r
162 xReturned = CyaSSL_set_fd( xCyaSSL_Object, xConnectedSocket );
\r
163 configASSERT( xReturned == SSL_SUCCESS );
\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
172 /* Print the received characters. */
\r
175 printf( "Received by the secure server: %s\r\n", cReceivedString );
\r
178 } while ( lBytes > 0 );
\r
180 /* The connection was closed, close the socket and free the
\r
182 closesocket( xConnectedSocket );
\r
183 CyaSSL_free( xCyaSSL_Object );
\r
184 printf( "Connection closed, back to start\r\n\r\n" );
\r
191 /* The socket could not be opened. */
\r
192 vTaskDelete( NULL );
\r
195 /*-----------------------------------------------------------*/
\r
197 static SOCKET prvOpenServerSocket( void )
\r
200 WORD wVersionRequested;
\r
201 struct sockaddr_in xConnection;
\r
202 SOCKET xSocket = INVALID_SOCKET;
\r
204 wVersionRequested = MAKEWORD( 2, 2 );
\r
206 /* Prepare to use WinSock. */
\r
207 if( WSAStartup( wVersionRequested, &xWSAData ) != 0 )
\r
209 fprintf( stderr, "Could not open Windows connection.\n" );
\r
213 xSocket = socket( AF_INET, SOCK_STREAM, 0 );
\r
214 if( xSocket == INVALID_SOCKET)
\r
216 fprintf( stderr, "Could not create socket.\n" );
\r
221 /* Zero out the server structure. */
\r
222 memset( ( void * ) &xConnection, 0x00, sizeof( struct sockaddr_in ) );
\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
228 /* Bind the address to the socket. */
\r
229 if( bind( xSocket, ( struct sockaddr * ) &xConnection, sizeof( struct sockaddr_in ) ) == -1 )
\r
231 fprintf( stderr, "Could not socket to port %d.\n", configTCP_PORT_NUMBER );
\r
232 closesocket( xSocket );
\r
233 xSocket = INVALID_SOCKET;
\r
237 if( listen( xSocket, 20 ) != 0 )
\r
239 closesocket( xSocket );
\r
240 xSocket = INVALID_SOCKET;
\r
248 /*-----------------------------------------------------------*/
\r
250 static void prvInitialiseCyaSSL( void )
\r
254 #ifdef DEBUG_CYASSL
\r
256 CyaSSL_Debugging_ON();
\r
260 /* Initialise CyaSSL. This must be done before any other CyaSSL functions
\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
267 if( xCyaSSL_ServerContext != NULL )
\r
269 /* Load the CA certificate. Real applications should ensure that
\r
270 CyaSSL_CTX_load_verify_locations() returns SSL_SUCCESS before
\r
272 iReturn = CyaSSL_CTX_load_verify_locations( xCyaSSL_ServerContext, "ca-cert.pem", 0 );
\r
273 configASSERT( iReturn == SSL_SUCCESS );
\r
275 iReturn = CyaSSL_CTX_use_certificate_file( xCyaSSL_ServerContext, "server-cert.pem", SSL_FILETYPE_PEM );
\r
276 configASSERT( iReturn == SSL_SUCCESS );
\r
278 iReturn = CyaSSL_CTX_use_PrivateKey_file( xCyaSSL_ServerContext, "server-key.pem", SSL_FILETYPE_PEM );
\r
279 configASSERT( iReturn == SSL_SUCCESS );
\r