blob: a215a9e197f87f37d9040576df314cf1b387d9df [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * SSL server demonstration program
3 *
Paul Bakker3c5ef712013-06-25 16:37:45 +02004 * Copyright (C) 2006-2013, Brainspark B.V.
Paul Bakkerb96f1542010-07-18 20:36:00 +00005 *
6 * This file is part of PolarSSL (http://www.polarssl.org)
Paul Bakker84f12b72010-07-18 10:13:04 +00007 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
Paul Bakkerb96f1542010-07-18 20:36:00 +00008 *
Paul Bakker77b385e2009-07-28 17:23:11 +00009 * All rights reserved.
Paul Bakkere0ccd0a2009-01-04 16:27:10 +000010 *
Paul Bakker5121ce52009-01-03 21:22:43 +000011 * 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 Bakker5121ce52009-01-03 21:22:43 +000031#include <windows.h>
32#endif
33
34#include <string.h>
35#include <stdlib.h>
36#include <stdio.h>
37
Paul Bakker5690efc2011-05-26 13:16:06 +000038#include "polarssl/config.h"
39
Paul Bakker508ad5a2011-12-04 17:09:26 +000040#include "polarssl/entropy.h"
41#include "polarssl/ctr_drbg.h"
Paul Bakker40e46942009-01-03 21:51:57 +000042#include "polarssl/certs.h"
43#include "polarssl/x509.h"
44#include "polarssl/ssl.h"
45#include "polarssl/net.h"
Paul Bakkera3d195c2011-11-27 21:07:34 +000046#include "polarssl/error.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000047
Paul Bakker0a597072012-09-25 21:55:46 +000048#if defined(POLARSSL_SSL_CACHE_C)
49#include "polarssl/ssl_cache.h"
50#endif
51
Paul Bakker5690efc2011-05-26 13:16:06 +000052#if !defined(POLARSSL_BIGNUM_C) || !defined(POLARSSL_CERTS_C) || \
Paul Bakker508ad5a2011-12-04 17:09:26 +000053 !defined(POLARSSL_ENTROPY_C) || !defined(POLARSSL_SSL_TLS_C) || \
Paul Bakkered27a042013-04-18 22:46:23 +020054 !defined(POLARSSL_SSL_SRV_C) || !defined(POLARSSL_NET_C) || \
55 !defined(POLARSSL_RSA_C) || !defined(POLARSSL_CTR_DRBG_C) || \
56 !defined(POLARSSL_X509_PARSE_C)
Paul Bakkercce9d772011-11-18 14:26:47 +000057int main( int argc, char *argv[] )
Paul Bakker5690efc2011-05-26 13:16:06 +000058{
Paul Bakkercce9d772011-11-18 14:26:47 +000059 ((void) argc);
60 ((void) argv);
61
Paul Bakker508ad5a2011-12-04 17:09:26 +000062 printf("POLARSSL_BIGNUM_C and/or POLARSSL_CERTS_C and/or POLARSSL_ENTROPY_C "
Paul Bakker5690efc2011-05-26 13:16:06 +000063 "and/or POLARSSL_SSL_TLS_C and/or POLARSSL_SSL_SRV_C and/or "
Paul Bakker508ad5a2011-12-04 17:09:26 +000064 "POLARSSL_NET_C and/or POLARSSL_RSA_C and/or "
Paul Bakkered27a042013-04-18 22:46:23 +020065 "POLARSSL_CTR_DRBG_C and/or POLARSSL_X509_PARSE_C not defined.\n");
Paul Bakker5690efc2011-05-26 13:16:06 +000066 return( 0 );
67}
68#else
Paul Bakker9a97c5d2013-09-15 17:07:33 +020069
70#define HTTP_RESPONSE \
71 "HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n" \
72 "<h2>PolarSSL Test Server</h2>\r\n" \
73 "<p>Successful connection using: %s</p>\r\n"
74
75#define DEBUG_LEVEL 0
76
77static void my_debug( void *ctx, int level, const char *str )
78{
79 if( level < DEBUG_LEVEL )
80 {
81 fprintf( (FILE *) ctx, "%s", str );
82 fflush( (FILE *) ctx );
83 }
84}
85
Paul Bakkercce9d772011-11-18 14:26:47 +000086int main( int argc, char *argv[] )
Paul Bakker5121ce52009-01-03 21:22:43 +000087{
88 int ret, len;
89 int listen_fd;
Paul Bakker7eb013f2011-10-06 12:37:39 +000090 int client_fd = -1;
Paul Bakker5121ce52009-01-03 21:22:43 +000091 unsigned char buf[1024];
Paul Bakkeref3f8c72013-06-24 13:01:08 +020092 const char *pers = "ssl_server";
Paul Bakker5121ce52009-01-03 21:22:43 +000093
Paul Bakker508ad5a2011-12-04 17:09:26 +000094 entropy_context entropy;
95 ctr_drbg_context ctr_drbg;
Paul Bakker5121ce52009-01-03 21:22:43 +000096 ssl_context ssl;
Paul Bakker5121ce52009-01-03 21:22:43 +000097 x509_cert srvcert;
Manuel Pégourié-Gonnardac755232013-08-19 14:10:16 +020098 pk_context pkey;
Paul Bakkerd4324102012-09-26 08:29:38 +000099#if defined(POLARSSL_SSL_CACHE_C)
100 ssl_cache_context cache;
101#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000102
Paul Bakkercce9d772011-11-18 14:26:47 +0000103 ((void) argc);
104 ((void) argv);
105
Paul Bakker0a597072012-09-25 21:55:46 +0000106#if defined(POLARSSL_SSL_CACHE_C)
Paul Bakker0a597072012-09-25 21:55:46 +0000107 ssl_cache_init( &cache );
108#endif
Paul Bakkerfab5c822012-02-06 16:45:10 +0000109
Paul Bakker5121ce52009-01-03 21:22:43 +0000110 /*
111 * 1. Load the certificates and private RSA key
112 */
113 printf( "\n . Loading the server cert. and key..." );
114 fflush( stdout );
115
116 memset( &srvcert, 0, sizeof( x509_cert ) );
117
118 /*
119 * This demonstration program uses embedded test certificates.
120 * Instead, you may want to use x509parse_crtfile() to read the
Manuel Pégourié-Gonnardac755232013-08-19 14:10:16 +0200121 * server and CA certificates, as well as x509parse_keyfile().
Paul Bakker5121ce52009-01-03 21:22:43 +0000122 */
Paul Bakkeref3f8c72013-06-24 13:01:08 +0200123 ret = x509parse_crt( &srvcert, (const unsigned char *) test_srv_crt,
Paul Bakker69e095c2011-12-10 21:55:01 +0000124 strlen( test_srv_crt ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000125 if( ret != 0 )
126 {
127 printf( " failed\n ! x509parse_crt returned %d\n\n", ret );
128 goto exit;
129 }
130
Paul Bakkeref3f8c72013-06-24 13:01:08 +0200131 ret = x509parse_crt( &srvcert, (const unsigned char *) test_ca_crt,
Paul Bakker69e095c2011-12-10 21:55:01 +0000132 strlen( test_ca_crt ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000133 if( ret != 0 )
134 {
135 printf( " failed\n ! x509parse_crt returned %d\n\n", ret );
136 goto exit;
137 }
138
Manuel Pégourié-Gonnardac755232013-08-19 14:10:16 +0200139 pk_init( &pkey );
Paul Bakker1a7550a2013-09-15 13:01:22 +0200140 ret = pk_parse_key( &pkey, (const unsigned char *) test_srv_key,
141 strlen( test_srv_key ), NULL, 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000142 if( ret != 0 )
143 {
Paul Bakker1a7550a2013-09-15 13:01:22 +0200144 printf( " failed\n ! pk_parse_key returned %d\n\n", ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000145 goto exit;
146 }
147
148 printf( " ok\n" );
149
150 /*
151 * 2. Setup the listening TCP socket
152 */
153 printf( " . Bind on https://localhost:4433/ ..." );
154 fflush( stdout );
155
156 if( ( ret = net_bind( &listen_fd, NULL, 4433 ) ) != 0 )
157 {
158 printf( " failed\n ! net_bind returned %d\n\n", ret );
159 goto exit;
160 }
161
162 printf( " ok\n" );
163
164 /*
Paul Bakker508ad5a2011-12-04 17:09:26 +0000165 * 3. Seed the RNG
Paul Bakker5121ce52009-01-03 21:22:43 +0000166 */
Paul Bakker508ad5a2011-12-04 17:09:26 +0000167 printf( " . Seeding the random number generator..." );
Paul Bakker5121ce52009-01-03 21:22:43 +0000168 fflush( stdout );
169
Paul Bakker508ad5a2011-12-04 17:09:26 +0000170 entropy_init( &entropy );
171 if( ( ret = ctr_drbg_init( &ctr_drbg, entropy_func, &entropy,
Paul Bakkeref3f8c72013-06-24 13:01:08 +0200172 (const unsigned char *) pers,
173 strlen( pers ) ) ) != 0 )
Paul Bakker508ad5a2011-12-04 17:09:26 +0000174 {
175 printf( " failed\n ! ctr_drbg_init returned %d\n", ret );
176 goto exit;
177 }
178
179 printf( " ok\n" );
180
181 /*
182 * 4. Setup stuff
183 */
184 printf( " . Setting up the SSL data...." );
185 fflush( stdout );
Paul Bakker5121ce52009-01-03 21:22:43 +0000186
187 if( ( ret = ssl_init( &ssl ) ) != 0 )
188 {
189 printf( " failed\n ! ssl_init returned %d\n\n", ret );
Paul Bakker7eb013f2011-10-06 12:37:39 +0000190 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000191 }
192
Paul Bakker5121ce52009-01-03 21:22:43 +0000193 ssl_set_endpoint( &ssl, SSL_IS_SERVER );
194 ssl_set_authmode( &ssl, SSL_VERIFY_NONE );
195
Paul Bakker508ad5a2011-12-04 17:09:26 +0000196 ssl_set_rng( &ssl, ctr_drbg_random, &ctr_drbg );
Paul Bakker5121ce52009-01-03 21:22:43 +0000197 ssl_set_dbg( &ssl, my_debug, stdout );
Paul Bakker7eb013f2011-10-06 12:37:39 +0000198
Paul Bakker0a597072012-09-25 21:55:46 +0000199#if defined(POLARSSL_SSL_CACHE_C)
200 ssl_set_session_cache( &ssl, ssl_cache_get, &cache,
201 ssl_cache_set, &cache );
202#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000203
Paul Bakker40ea7de2009-05-03 10:18:48 +0000204 ssl_set_ca_chain( &ssl, srvcert.next, NULL, NULL );
Manuel Pégourié-Gonnardac755232013-08-19 14:10:16 +0200205 ssl_set_own_cert( &ssl, &srvcert, &pkey );
Paul Bakker5121ce52009-01-03 21:22:43 +0000206
Paul Bakker7eb013f2011-10-06 12:37:39 +0000207 printf( " ok\n" );
208
209reset:
Paul Bakkera3d195c2011-11-27 21:07:34 +0000210#ifdef POLARSSL_ERROR_C
211 if( ret != 0 )
212 {
213 char error_buf[100];
Paul Bakker03a8a792013-06-30 12:18:08 +0200214 polarssl_strerror( ret, error_buf, 100 );
Paul Bakkera3d195c2011-11-27 21:07:34 +0000215 printf("Last error was: %d - %s\n\n", ret, error_buf );
216 }
217#endif
218
Paul Bakker7eb013f2011-10-06 12:37:39 +0000219 if( client_fd != -1 )
220 net_close( client_fd );
221
222 ssl_session_reset( &ssl );
223
224 /*
225 * 3. Wait until a client connects
226 */
Paul Bakkercce9d772011-11-18 14:26:47 +0000227#if defined(_WIN32_WCE)
228 {
229 SHELLEXECUTEINFO sei;
230
231 ZeroMemory( &sei, sizeof( SHELLEXECUTEINFO ) );
232
233 sei.cbSize = sizeof( SHELLEXECUTEINFO );
234 sei.fMask = 0;
235 sei.hwnd = 0;
236 sei.lpVerb = _T( "open" );
237 sei.lpFile = _T( "https://localhost:4433/" );
238 sei.lpParameters = NULL;
239 sei.lpDirectory = NULL;
240 sei.nShow = SW_SHOWNORMAL;
241
242 ShellExecuteEx( &sei );
243 }
244#elif defined(_WIN32)
Paul Bakker7eb013f2011-10-06 12:37:39 +0000245 ShellExecute( NULL, "open", "https://localhost:4433/",
246 NULL, NULL, SW_SHOWNORMAL );
247#endif
248
249 client_fd = -1;
250
251 printf( " . Waiting for a remote connection ..." );
252 fflush( stdout );
253
254 if( ( ret = net_accept( listen_fd, &client_fd, NULL ) ) != 0 )
255 {
256 printf( " failed\n ! net_accept returned %d\n\n", ret );
257 goto exit;
258 }
259
260 ssl_set_bio( &ssl, net_recv, &client_fd,
261 net_send, &client_fd );
262
263 printf( " ok\n" );
264
Paul Bakker5121ce52009-01-03 21:22:43 +0000265 /*
266 * 5. Handshake
267 */
268 printf( " . Performing the SSL/TLS handshake..." );
269 fflush( stdout );
270
271 while( ( ret = ssl_handshake( &ssl ) ) != 0 )
272 {
Paul Bakker831a7552011-05-18 13:32:51 +0000273 if( ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE )
Paul Bakker5121ce52009-01-03 21:22:43 +0000274 {
275 printf( " failed\n ! ssl_handshake returned %d\n\n", ret );
Paul Bakker7eb013f2011-10-06 12:37:39 +0000276 goto reset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000277 }
278 }
279
280 printf( " ok\n" );
281
282 /*
283 * 6. Read the HTTP Request
284 */
285 printf( " < Read from client:" );
286 fflush( stdout );
287
288 do
289 {
290 len = sizeof( buf ) - 1;
291 memset( buf, 0, sizeof( buf ) );
292 ret = ssl_read( &ssl, buf, len );
293
Paul Bakker831a7552011-05-18 13:32:51 +0000294 if( ret == POLARSSL_ERR_NET_WANT_READ || ret == POLARSSL_ERR_NET_WANT_WRITE )
Paul Bakker5121ce52009-01-03 21:22:43 +0000295 continue;
296
297 if( ret <= 0 )
298 {
299 switch( ret )
300 {
Paul Bakker40e46942009-01-03 21:51:57 +0000301 case POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY:
Paul Bakker5121ce52009-01-03 21:22:43 +0000302 printf( " connection was closed gracefully\n" );
303 break;
304
Paul Bakker40e46942009-01-03 21:51:57 +0000305 case POLARSSL_ERR_NET_CONN_RESET:
Paul Bakker5121ce52009-01-03 21:22:43 +0000306 printf( " connection was reset by peer\n" );
307 break;
308
309 default:
Paul Bakker6f3578c2012-04-16 06:46:01 +0000310 printf( " ssl_read returned -0x%x\n", -ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000311 break;
312 }
313
314 break;
315 }
316
317 len = ret;
318 printf( " %d bytes read\n\n%s", len, (char *) buf );
Paul Bakker48916f92012-09-16 19:57:18 +0000319
320 if( ret > 0 )
321 break;
Paul Bakker5121ce52009-01-03 21:22:43 +0000322 }
Paul Bakker48916f92012-09-16 19:57:18 +0000323 while( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000324
325 /*
326 * 7. Write the 200 Response
327 */
328 printf( " > Write to client:" );
329 fflush( stdout );
330
331 len = sprintf( (char *) buf, HTTP_RESPONSE,
Paul Bakkere3166ce2011-01-27 17:40:50 +0000332 ssl_get_ciphersuite( &ssl ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000333
334 while( ( ret = ssl_write( &ssl, buf, len ) ) <= 0 )
335 {
Paul Bakker40e46942009-01-03 21:51:57 +0000336 if( ret == POLARSSL_ERR_NET_CONN_RESET )
Paul Bakker5121ce52009-01-03 21:22:43 +0000337 {
338 printf( " failed\n ! peer closed the connection\n\n" );
Paul Bakker7eb013f2011-10-06 12:37:39 +0000339 goto reset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000340 }
341
Paul Bakker831a7552011-05-18 13:32:51 +0000342 if( ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE )
Paul Bakker5121ce52009-01-03 21:22:43 +0000343 {
344 printf( " failed\n ! ssl_write returned %d\n\n", ret );
345 goto exit;
346 }
347 }
348
349 len = ret;
350 printf( " %d bytes written\n\n%s\n", len, (char *) buf );
Paul Bakkera3d195c2011-11-27 21:07:34 +0000351
Paul Bakkera3d195c2011-11-27 21:07:34 +0000352 ret = 0;
Paul Bakker7eb013f2011-10-06 12:37:39 +0000353 goto reset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000354
355exit:
356
Paul Bakkera3d195c2011-11-27 21:07:34 +0000357#ifdef POLARSSL_ERROR_C
358 if( ret != 0 )
359 {
360 char error_buf[100];
Paul Bakker03a8a792013-06-30 12:18:08 +0200361 polarssl_strerror( ret, error_buf, 100 );
Paul Bakkera3d195c2011-11-27 21:07:34 +0000362 printf("Last error was: %d - %s\n\n", ret, error_buf );
363 }
364#endif
365
Paul Bakker5121ce52009-01-03 21:22:43 +0000366 net_close( client_fd );
367 x509_free( &srvcert );
Manuel Pégourié-Gonnardac755232013-08-19 14:10:16 +0200368 pk_free( &pkey );
Paul Bakker5121ce52009-01-03 21:22:43 +0000369 ssl_free( &ssl );
Paul Bakker0a597072012-09-25 21:55:46 +0000370#if defined(POLARSSL_SSL_CACHE_C)
371 ssl_cache_free( &cache );
372#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000373
Paul Bakkercce9d772011-11-18 14:26:47 +0000374#if defined(_WIN32)
Paul Bakker5121ce52009-01-03 21:22:43 +0000375 printf( " Press Enter to exit this program.\n" );
376 fflush( stdout ); getchar();
377#endif
378
379 return( ret );
380}
Paul Bakker508ad5a2011-12-04 17:09:26 +0000381#endif /* POLARSSL_BIGNUM_C && POLARSSL_CERTS_C && POLARSSL_ENTROPY_C &&
Paul Bakker5690efc2011-05-26 13:16:06 +0000382 POLARSSL_SSL_TLS_C && POLARSSL_SSL_SRV_C && POLARSSL_NET_C &&
Paul Bakker508ad5a2011-12-04 17:09:26 +0000383 POLARSSL_RSA_C && POLARSSL_CTR_DRBG_C */