blob: 89f834aad3cde63aad357f21ad2394735d4b75d9 [file] [log] [blame]
Paul Bakker896ac222011-05-20 12:33:05 +00001/*
Paul Bakkercb79ae0b2011-05-20 12:44:16 +00002 * SSL server demonstration program using fork() for handling multiple clients
Paul Bakker896ac222011-05-20 12:33:05 +00003 *
Paul Bakkercce9d772011-11-18 14:26:47 +00004 * Copyright (C) 2006-2011, Brainspark B.V.
Paul Bakker896ac222011-05-20 12:33:05 +00005 *
6 * This file is part of PolarSSL (http://www.polarssl.org)
7 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
8 *
9 * All rights reserved.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 */
25
26#ifndef _CRT_SECURE_NO_DEPRECATE
27#define _CRT_SECURE_NO_DEPRECATE 1
28#endif
29
Paul Bakkercce9d772011-11-18 14:26:47 +000030#if defined(_WIN32)
Paul Bakker896ac222011-05-20 12:33:05 +000031#include <windows.h>
32#endif
33
34#include <string.h>
35#include <stdlib.h>
36#include <stdio.h>
37#include <unistd.h>
38#include <signal.h>
39
Paul Bakker5690efc2011-05-26 13:16:06 +000040#include "polarssl/config.h"
41
Paul Bakker508ad5a2011-12-04 17:09:26 +000042#include "polarssl/entropy.h"
43#include "polarssl/ctr_drbg.h"
Paul Bakker896ac222011-05-20 12:33:05 +000044#include "polarssl/certs.h"
45#include "polarssl/x509.h"
46#include "polarssl/ssl.h"
47#include "polarssl/net.h"
48#include "polarssl/timing.h"
49
50#define HTTP_RESPONSE \
51 "HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n" \
52 "<h2>PolarSSL Test Server</h2>\r\n" \
53 "<p>Successful connection using: %s</p>\r\n"
54
Paul Bakkerb892b132011-10-12 09:19:43 +000055#if !defined(POLARSSL_BIGNUM_C) || !defined(POLARSSL_CERTS_C) || \
Paul Bakker508ad5a2011-12-04 17:09:26 +000056 !defined(POLARSSL_ENTROPY_C) || !defined(POLARSSL_SSL_TLS_C) || \
Paul Bakkerb892b132011-10-12 09:19:43 +000057 !defined(POLARSSL_SSL_SRV_C) || !defined(POLARSSL_NET_C) || \
Paul Bakkered27a042013-04-18 22:46:23 +020058 !defined(POLARSSL_RSA_C) || !defined(POLARSSL_CTR_DRBG_C) || \
59 !defined(POLARSSL_X509_PARSE_C)
Paul Bakkercce9d772011-11-18 14:26:47 +000060int main( int argc, char *argv[] )
Paul Bakkerb892b132011-10-12 09:19:43 +000061{
Paul Bakkercce9d772011-11-18 14:26:47 +000062 ((void) argc);
63 ((void) argv);
64
Paul Bakker508ad5a2011-12-04 17:09:26 +000065 printf("POLARSSL_BIGNUM_C and/or POLARSSL_CERTS_C and/or POLARSSL_ENTROPY_C "
Paul Bakkerb892b132011-10-12 09:19:43 +000066 "and/or POLARSSL_SSL_TLS_C and/or POLARSSL_SSL_SRV_C and/or "
Paul Bakker508ad5a2011-12-04 17:09:26 +000067 "POLARSSL_NET_C and/or POLARSSL_RSA_C and/or "
Paul Bakkered27a042013-04-18 22:46:23 +020068 "POLARSSL_CTR_DRBG_C and/or POLARSSL_X509_PARSE_C not defined.\n");
Paul Bakkerb892b132011-10-12 09:19:43 +000069 return( 0 );
70}
Paul Bakkercce9d772011-11-18 14:26:47 +000071#elif defined(_WIN32)
72int main( int argc, char *argv[] )
Paul Bakkerb892b132011-10-12 09:19:43 +000073{
Paul Bakkercce9d772011-11-18 14:26:47 +000074 ((void) argc);
75 ((void) argv);
76
77 printf("_WIN32 defined. This application requires fork() and signals "
Paul Bakkerb892b132011-10-12 09:19:43 +000078 "to work correctly.\n");
79 return( 0 );
80}
81#else
Paul Bakker896ac222011-05-20 12:33:05 +000082
83#define DEBUG_LEVEL 0
84
85void my_debug( void *ctx, int level, const char *str )
86{
87 if( level < DEBUG_LEVEL )
88 {
89 fprintf( (FILE *) ctx, "%s", str );
90 fflush( (FILE *) ctx );
91 }
92}
93
Paul Bakkercce9d772011-11-18 14:26:47 +000094int main( int argc, char *argv[] )
Paul Bakker896ac222011-05-20 12:33:05 +000095{
96 int ret, len, cnt = 0, pid;
97 int listen_fd;
98 int client_fd;
99 unsigned char buf[1024];
Paul Bakkeref3f8c72013-06-24 13:01:08 +0200100 const char *pers = "ssl_fork_server";
Paul Bakker896ac222011-05-20 12:33:05 +0000101
Paul Bakker508ad5a2011-12-04 17:09:26 +0000102 entropy_context entropy;
103 ctr_drbg_context ctr_drbg;
Paul Bakker896ac222011-05-20 12:33:05 +0000104 ssl_context ssl;
Paul Bakker896ac222011-05-20 12:33:05 +0000105 x509_cert srvcert;
106 rsa_context rsa;
107
Paul Bakkercce9d772011-11-18 14:26:47 +0000108 ((void) argc);
109 ((void) argv);
110
Paul Bakker896ac222011-05-20 12:33:05 +0000111 signal( SIGCHLD, SIG_IGN );
112
113 /*
Paul Bakker508ad5a2011-12-04 17:09:26 +0000114 * 0. Initial seeding of the RNG
115 */
116 printf( "\n . Initial seeding of the random generator..." );
117 fflush( stdout );
118
119 entropy_init( &entropy );
120 if( ( ret = ctr_drbg_init( &ctr_drbg, entropy_func, &entropy,
Paul Bakkeref3f8c72013-06-24 13:01:08 +0200121 (const unsigned char *) pers,
122 strlen( pers ) ) ) != 0 )
Paul Bakker508ad5a2011-12-04 17:09:26 +0000123 {
124 printf( " failed\n ! ctr_drbg_init returned %d\n", ret );
125 goto exit;
126 }
127
128 printf( " ok\n" );
129
130 /*
Paul Bakker896ac222011-05-20 12:33:05 +0000131 * 1. Load the certificates and private RSA key
132 */
Paul Bakker508ad5a2011-12-04 17:09:26 +0000133 printf( " . Loading the server cert. and key..." );
Paul Bakker896ac222011-05-20 12:33:05 +0000134 fflush( stdout );
135
136 memset( &srvcert, 0, sizeof( x509_cert ) );
137
138 /*
139 * This demonstration program uses embedded test certificates.
140 * Instead, you may want to use x509parse_crtfile() to read the
141 * server and CA certificates, as well as x509parse_keyfile().
142 */
Paul Bakkeref3f8c72013-06-24 13:01:08 +0200143 ret = x509parse_crt( &srvcert, (const unsigned char *) test_srv_crt,
Paul Bakker69e095c2011-12-10 21:55:01 +0000144 strlen( test_srv_crt ) );
Paul Bakker896ac222011-05-20 12:33:05 +0000145 if( ret != 0 )
146 {
147 printf( " failed\n ! x509parse_crt returned %d\n\n", ret );
148 goto exit;
149 }
150
Paul Bakkeref3f8c72013-06-24 13:01:08 +0200151 ret = x509parse_crt( &srvcert, (const unsigned char *) test_ca_crt,
Paul Bakker69e095c2011-12-10 21:55:01 +0000152 strlen( test_ca_crt ) );
Paul Bakker896ac222011-05-20 12:33:05 +0000153 if( ret != 0 )
154 {
155 printf( " failed\n ! x509parse_crt returned %d\n\n", ret );
156 goto exit;
157 }
158
159 rsa_init( &rsa, RSA_PKCS_V15, 0 );
Paul Bakkeref3f8c72013-06-24 13:01:08 +0200160 ret = x509parse_key( &rsa, (const unsigned char *) test_srv_key,
Paul Bakker896ac222011-05-20 12:33:05 +0000161 strlen( test_srv_key ), NULL, 0 );
162 if( ret != 0 )
163 {
164 printf( " failed\n ! x509parse_key returned %d\n\n", ret );
165 goto exit;
166 }
167
168 printf( " ok\n" );
169
170 /*
171 * 2. Setup the listening TCP socket
172 */
173 printf( " . Bind on https://localhost:4433/ ..." );
174 fflush( stdout );
175
176 if( ( ret = net_bind( &listen_fd, NULL, 4433 ) ) != 0 )
177 {
178 printf( " failed\n ! net_bind returned %d\n\n", ret );
179 goto exit;
180 }
181
182 printf( " ok\n" );
183
184 while( 1 )
185 {
186 /*
187 * 3. Wait until a client connects
188 */
189 client_fd = -1;
190 memset( &ssl, 0, sizeof( ssl ) );
191
192 printf( " . Waiting for a remote connection ..." );
193 fflush( stdout );
194
195 if( ( ret = net_accept( listen_fd, &client_fd, NULL ) ) != 0 )
196 {
197 printf( " failed\n ! net_accept returned %d\n\n", ret );
198 goto exit;
199 }
200
201 printf( " ok\n" );
202
203 /*
204 * 3.5. Forking server thread
205 */
206
207 pid = fork();
208
209 printf( " . Forking to handle connection ..." );
210 fflush( stdout );
211
212 if( pid < 0 )
213 {
214 printf(" failed\n ! fork returned %d\n\n", pid );
215 goto exit;
216 }
217
218 printf( " ok\n" );
219
220 if( pid != 0 )
221 {
Paul Bakker508ad5a2011-12-04 17:09:26 +0000222 if( ( ret = ctr_drbg_reseed( &ctr_drbg,
Paul Bakkeref3f8c72013-06-24 13:01:08 +0200223 (const unsigned char *) "parent",
224 6 ) ) != 0 )
Paul Bakker508ad5a2011-12-04 17:09:26 +0000225 {
226 printf( " failed\n ! ctr_drbg_reseed returned %d\n", ret );
227 goto exit;
228 }
229
Paul Bakker896ac222011-05-20 12:33:05 +0000230 close( client_fd );
231 continue;
232 }
233
234 close( listen_fd );
235
236 /*
237 * 4. Setup stuff
238 */
Paul Bakker508ad5a2011-12-04 17:09:26 +0000239 printf( " . Setting up the SSL data...." );
Paul Bakker896ac222011-05-20 12:33:05 +0000240 fflush( stdout );
241
Paul Bakker508ad5a2011-12-04 17:09:26 +0000242 if( ( ret = ctr_drbg_reseed( &ctr_drbg,
Paul Bakkeref3f8c72013-06-24 13:01:08 +0200243 (const unsigned char *) "child",
244 5 ) ) != 0 )
Paul Bakker508ad5a2011-12-04 17:09:26 +0000245 {
246 printf( " failed\n ! ctr_drbg_reseed returned %d\n", ret );
247 goto exit;
248 }
249
Paul Bakker896ac222011-05-20 12:33:05 +0000250 if( ( ret = ssl_init( &ssl ) ) != 0 )
251 {
252 printf( " failed\n ! ssl_init returned %d\n\n", ret );
253 goto exit;
254 }
255
256 printf( " ok\n" );
257
258 ssl_set_endpoint( &ssl, SSL_IS_SERVER );
259 ssl_set_authmode( &ssl, SSL_VERIFY_NONE );
260
Paul Bakker508ad5a2011-12-04 17:09:26 +0000261 ssl_set_rng( &ssl, ctr_drbg_random, &ctr_drbg );
Paul Bakker896ac222011-05-20 12:33:05 +0000262 ssl_set_dbg( &ssl, my_debug, stdout );
263 ssl_set_bio( &ssl, net_recv, &client_fd,
264 net_send, &client_fd );
Paul Bakker896ac222011-05-20 12:33:05 +0000265
Paul Bakker896ac222011-05-20 12:33:05 +0000266 ssl_set_ca_chain( &ssl, srvcert.next, NULL, NULL );
267 ssl_set_own_cert( &ssl, &srvcert, &rsa );
Paul Bakker896ac222011-05-20 12:33:05 +0000268
269 /*
270 * 5. Handshake
271 */
272 printf( " . Performing the SSL/TLS handshake..." );
273 fflush( stdout );
274
275 while( ( ret = ssl_handshake( &ssl ) ) != 0 )
276 {
277 if( ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE )
278 {
279 printf( " failed\n ! ssl_handshake returned %d\n\n", ret );
280 goto exit;
281 }
282 }
283
284 printf( " ok\n" );
285
286 /*
287 * 6. Read the HTTP Request
288 */
289 printf( " < Read from client:" );
290 fflush( stdout );
291
292 do
293 {
294 len = sizeof( buf ) - 1;
295 memset( buf, 0, sizeof( buf ) );
296 ret = ssl_read( &ssl, buf, len );
297
298 if( ret == POLARSSL_ERR_NET_WANT_READ || ret == POLARSSL_ERR_NET_WANT_WRITE )
299 continue;
300
301 if( ret <= 0 )
302 {
303 switch( ret )
304 {
305 case POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY:
306 printf( " connection was closed gracefully\n" );
307 break;
308
309 case POLARSSL_ERR_NET_CONN_RESET:
310 printf( " connection was reset by peer\n" );
311 break;
312
313 default:
314 printf( " ssl_read returned %d\n", ret );
315 break;
316 }
317
318 break;
319 }
320
321 len = ret;
322 printf( " %d bytes read\n\n%s", len, (char *) buf );
323 }
324 while( 0 );
325
326 /*
327 * 7. Write the 200 Response
328 */
329 printf( " > Write to client:" );
330 fflush( stdout );
331
332 len = sprintf( (char *) buf, HTTP_RESPONSE,
333 ssl_get_ciphersuite( &ssl ) );
334
335 while( cnt < 100 )
336 {
337 while( ( ret = ssl_write( &ssl, buf, len ) ) <= 0 )
338 {
339 if( ret == POLARSSL_ERR_NET_CONN_RESET )
340 {
341 printf( " failed\n ! peer closed the connection\n\n" );
342 goto exit;
343 }
344
345 if( ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE )
346 {
347 printf( " failed\n ! ssl_write returned %d\n\n", ret );
348 goto exit;
349 }
350 }
351 len = ret;
352 printf( " %d bytes written\n\n%s\n", len, (char *) buf );
353
354 m_sleep( 1000 );
355 }
356
357 ssl_close_notify( &ssl );
358 goto exit;
359 }
360
361exit:
362
363 net_close( client_fd );
364 x509_free( &srvcert );
365 rsa_free( &rsa );
366 ssl_free( &ssl );
367
Paul Bakkercce9d772011-11-18 14:26:47 +0000368#if defined(_WIN32)
Paul Bakker896ac222011-05-20 12:33:05 +0000369 printf( " Press Enter to exit this program.\n" );
370 fflush( stdout ); getchar();
371#endif
372
373 return( ret );
374}
Paul Bakker508ad5a2011-12-04 17:09:26 +0000375#endif /* POLARSSL_BIGNUM_C && POLARSSL_CERTS_C && POLARSSL_ENTROPY_C &&
Paul Bakker5690efc2011-05-26 13:16:06 +0000376 POLARSSL_SSL_TLS_C && POLARSSL_SSL_SRV_C && POLARSSL_NET_C &&
Paul Bakker508ad5a2011-12-04 17:09:26 +0000377 POLARSSL_RSA_C && POLARSSL_CTR_DRBG_C */