2 FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd.
\r
5 VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
\r
7 ***************************************************************************
\r
9 * FreeRTOS provides completely free yet professionally developed, *
\r
10 * robust, strictly quality controlled, supported, and cross *
\r
11 * platform software that has become a de facto standard. *
\r
13 * Help yourself get started quickly and support the FreeRTOS *
\r
14 * project by purchasing a FreeRTOS tutorial book, reference *
\r
15 * manual, or both from: http://www.FreeRTOS.org/Documentation *
\r
19 ***************************************************************************
\r
21 This file is part of the FreeRTOS distribution.
\r
23 FreeRTOS is free software; you can redistribute it and/or modify it under
\r
24 the terms of the GNU General Public License (version 2) as published by the
\r
25 Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
\r
27 >>! NOTE: The modification to the GPL is included to allow you to !<<
\r
28 >>! distribute a combined work that includes FreeRTOS without being !<<
\r
29 >>! obliged to provide the source code for proprietary components !<<
\r
30 >>! outside of the FreeRTOS kernel. !<<
\r
32 FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
\r
33 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
\r
34 FOR A PARTICULAR PURPOSE. Full license text is available from the following
\r
35 link: http://www.freertos.org/a00114.html
\r
39 ***************************************************************************
\r
41 * Having a problem? Start by reading the FAQ "My application does *
\r
42 * not run, what could be wrong?" *
\r
44 * http://www.FreeRTOS.org/FAQHelp.html *
\r
46 ***************************************************************************
\r
48 http://www.FreeRTOS.org - Documentation, books, training, latest versions,
\r
49 license and Real Time Engineers Ltd. contact details.
\r
51 http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
\r
52 including FreeRTOS+Trace - an indispensable productivity tool, a DOS
\r
53 compatible FAT file system, and our tiny thread aware UDP/IP stack.
\r
55 http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
\r
56 Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
\r
57 licenses offer ticketed support, indemnification and middleware.
\r
59 http://www.SafeRTOS.com - High Integrity Systems also provide a safety
\r
60 engineered and independently SIL3 certified version for use in safety and
\r
61 mission critical applications that require provable dependability.
\r
66 #pragma comment( lib, "ws2_32.lib" )
\r
68 /* Win32 includes. */
\r
69 #include <WinSock2.h>
\r
71 /* CyaSSL includes. */
\r
72 #include "cyassl/ssl.h"
\r
74 /* Standard includes. */
\r
78 /* FreeRTOS includes. */
\r
79 #include "FreeRTOS.h"
\r
82 /* This application is using the FreeRTOS Windows simulator, which uses the
\r
83 FreeRTOS scheduler to schedule FreeRTOS task within the Windows environment.
\r
84 The Windows envrionment must not be allowed to block any Windows threads that
\r
85 are running FreeRTOS tasks, unless the FreeRTOS task is running at the FreeRTOS
\r
86 idle priority. For simplicity, this demo uses the Windows TCP/IP stack, the
\r
87 API for which can cause Windows threads to block. Therefore, any FreeRTOS task
\r
88 that makes calls to the Windows TCP/IP stack must be assigned the idle prioity.
\r
89 Note this is only a restriction of the simulated Windows environment - real
\r
90 FreeRTOS ports do not have this restriction. */
\r
91 #define sstSECURE_CLIENT_TASK_PRIORITY ( tskIDLE_PRIORITY )
\r
93 /*-----------------------------------------------------------*/
\r
96 * Open, configures and binds the server's TCP socket.
\r
98 static SOCKET prvOpenServerSocket( void );
\r
101 * Prepare the CyaSSL library for use.
\r
103 static void prvInitialiseCyaSSL( void );
\r
106 * The task that implements the client side of the connection.
\r
108 extern void vSecureTCPClientTask( void *pvParameters );
\r
110 /*-----------------------------------------------------------*/
\r
112 /* The CyaSSL context for the server. */
\r
113 static CYASSL_CTX* xCyaSSL_ServerContext = NULL;
\r
115 /*-----------------------------------------------------------*/
\r
117 /* See the comments at the top of main.c. */
\r
118 void vSecureTCPServerTask( void *pvParameters )
\r
120 BaseType_t xReturned;
\r
122 uint8_t cReceivedString[ 60 ];
\r
123 struct sockaddr_in xClient;
\r
124 int xClientAddressLength = sizeof( struct sockaddr_in );
\r
125 SOCKET xListeningSocket, xConnectedSocket;
\r
126 CYASSL* xCyaSSL_Object; /* Only one connection is accepted at a time, so only one object is needed at a time. */
\r
128 /* Just to prevent compiler warnings. */
\r
129 ( void ) pvParameters;
\r
131 /* Perform the initialisation necessary before CyaSSL can be used. */
\r
132 prvInitialiseCyaSSL();
\r
133 configASSERT( xCyaSSL_ServerContext );
\r
135 /* Attempt to open the socket. */
\r
136 xListeningSocket = prvOpenServerSocket();
\r
138 /* Now the server socket has been created and the CyaSSL library has been
\r
139 initialised, the task that implements the client side can be created. */
\r
140 xTaskCreate( vSecureTCPClientTask, "Client", configMINIMAL_STACK_SIZE, NULL, sstSECURE_CLIENT_TASK_PRIORITY, NULL );
\r
142 if( xListeningSocket != INVALID_SOCKET )
\r
146 /* Wait until the client connects. */
\r
147 printf( "Waiting for new connection\r\n" );
\r
148 xConnectedSocket = accept( xListeningSocket, ( struct sockaddr * ) &xClient, &xClientAddressLength );
\r
150 if( xConnectedSocket != INVALID_SOCKET )
\r
152 printf( "Connection established\r\n" );
\r
154 /* A connection has been accepted by the server. Create a
\r
155 CyaSSL object for use with the newly connected socket. */
\r
156 xCyaSSL_Object = NULL;
\r
157 xCyaSSL_Object = CyaSSL_new( xCyaSSL_ServerContext );
\r
159 if( xCyaSSL_Object != NULL )
\r
161 /* Associate the created CyaSSL object with the connected
\r
163 xReturned = CyaSSL_set_fd( xCyaSSL_Object, xConnectedSocket );
\r
164 configASSERT( xReturned == SSL_SUCCESS );
\r
168 /* The next line is the secure equivalent to the
\r
169 standard sockets call:
\r
170 lBytes = recv( xConnectedSocket, cReceivedString, 50, 0 ); */
\r
171 lBytes = CyaSSL_read( xCyaSSL_Object, cReceivedString, sizeof( cReceivedString ) );
\r
173 /* Print the received characters. */
\r
176 printf( "Received by the secure server: %s\r\n", cReceivedString );
\r
179 } while ( lBytes > 0 );
\r
181 /* The connection was closed, close the socket and free the
\r
183 closesocket( xConnectedSocket );
\r
184 CyaSSL_free( xCyaSSL_Object );
\r
185 printf( "Connection closed, back to start\r\n\r\n" );
\r
192 /* The socket could not be opened. */
\r
193 vTaskDelete( NULL );
\r
196 /*-----------------------------------------------------------*/
\r
198 static SOCKET prvOpenServerSocket( void )
\r
201 WORD wVersionRequested;
\r
202 struct sockaddr_in xConnection;
\r
203 SOCKET xSocket = INVALID_SOCKET;
\r
205 wVersionRequested = MAKEWORD( 2, 2 );
\r
207 /* Prepare to use WinSock. */
\r
208 if( WSAStartup( wVersionRequested, &xWSAData ) != 0 )
\r
210 fprintf( stderr, "Could not open Windows connection.\n" );
\r
214 xSocket = socket( AF_INET, SOCK_STREAM, 0 );
\r
215 if( xSocket == INVALID_SOCKET)
\r
217 fprintf( stderr, "Could not create socket.\n" );
\r
222 /* Zero out the server structure. */
\r
223 memset( ( void * ) &xConnection, 0x00, sizeof( struct sockaddr_in ) );
\r
225 xConnection.sin_family = AF_INET;
\r
226 xConnection.sin_addr.s_addr = inet_addr("127.0.0.1");
\r
227 xConnection.sin_port = htons( configTCP_PORT_NUMBER );
\r
229 /* Bind the address to the socket. */
\r
230 if( bind( xSocket, ( struct sockaddr * ) &xConnection, sizeof( struct sockaddr_in ) ) == -1 )
\r
232 fprintf( stderr, "Could not socket to port %d.\n", configTCP_PORT_NUMBER );
\r
233 closesocket( xSocket );
\r
234 xSocket = INVALID_SOCKET;
\r
238 if( listen( xSocket, 20 ) != 0 )
\r
240 closesocket( xSocket );
\r
241 xSocket = INVALID_SOCKET;
\r
249 /*-----------------------------------------------------------*/
\r
251 static void prvInitialiseCyaSSL( void )
\r
255 #ifdef DEBUG_CYASSL
\r
257 CyaSSL_Debugging_ON();
\r
261 /* Initialise CyaSSL. This must be done before any other CyaSSL functions
\r
265 /* Attempt to create a context that uses the TLS V1 server protocol. */
\r
266 xCyaSSL_ServerContext = CyaSSL_CTX_new( CyaTLSv1_server_method() );
\r
268 if( xCyaSSL_ServerContext != NULL )
\r
270 /* Load the CA certificate. Real applications should ensure that
\r
271 CyaSSL_CTX_load_verify_locations() returns SSL_SUCCESS before
\r
273 iReturn = CyaSSL_CTX_load_verify_locations( xCyaSSL_ServerContext, "ca-cert.pem", 0 );
\r
274 configASSERT( iReturn == SSL_SUCCESS );
\r
276 iReturn = CyaSSL_CTX_use_certificate_file( xCyaSSL_ServerContext, "server-cert.pem", SSL_FILETYPE_PEM );
\r
277 configASSERT( iReturn == SSL_SUCCESS );
\r
279 iReturn = CyaSSL_CTX_use_PrivateKey_file( xCyaSSL_ServerContext, "server-key.pem", SSL_FILETYPE_PEM );
\r
280 configASSERT( iReturn == SSL_SUCCESS );
\r