blob: 052e56d0d2ba7e5c21cbb2d087b463ab41a2105a [file] [log] [blame]
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001/*
2 * SSL client with options
3 *
Paul Bakker3c5ef712013-06-25 16:37:45 +02004 * Copyright (C) 2006-2013, Brainspark B.V.
Paul Bakkerb60b95f2012-09-25 09:05:17 +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
Manuel Pégourié-Gonnardabd6e022013-09-20 13:30:43 +020026#include "polarssl/config.h"
Paul Bakkerb60b95f2012-09-25 09:05:17 +000027
Manuel Pégourié-Gonnard5d917ff2014-02-21 16:52:06 +010028#if defined(POLARSSL_SSL_SERVER_NAME_INDICATION) && defined(POLARSSL_FS_IO)
29#define POLARSSL_SNI
30#endif
31
32#if defined(POLARSSL_PLATFORM_C)
33#include "polarssl/platform.h"
34#else
35#define polarssl_malloc malloc
36#define polarssl_free free
37#endif
38
Paul Bakkerb60b95f2012-09-25 09:05:17 +000039#if defined(_WIN32)
40#include <windows.h>
41#endif
42
43#include <string.h>
44#include <stdlib.h>
45#include <stdio.h>
46
Paul Bakkerb60b95f2012-09-25 09:05:17 +000047#include "polarssl/net.h"
48#include "polarssl/ssl.h"
49#include "polarssl/entropy.h"
50#include "polarssl/ctr_drbg.h"
51#include "polarssl/certs.h"
52#include "polarssl/x509.h"
53#include "polarssl/error.h"
54
Paul Bakker0a597072012-09-25 21:55:46 +000055#if defined(POLARSSL_SSL_CACHE_C)
56#include "polarssl/ssl_cache.h"
57#endif
58
Paul Bakker82024bf2013-07-04 11:52:32 +020059#if defined(POLARSSL_MEMORY_BUFFER_ALLOC_C)
60#include "polarssl/memory.h"
61#endif
62
Manuel Pégourié-Gonnard18d31f82013-12-13 16:21:41 +010063#define DFL_SERVER_ADDR NULL
Paul Bakkerb60b95f2012-09-25 09:05:17 +000064#define DFL_SERVER_PORT 4433
Paul Bakkerb60b95f2012-09-25 09:05:17 +000065#define DFL_DEBUG_LEVEL 0
66#define DFL_CA_FILE ""
67#define DFL_CA_PATH ""
68#define DFL_CRT_FILE ""
69#define DFL_KEY_FILE ""
Manuel Pégourié-Gonnard3ebb2cd2013-09-23 17:00:18 +020070#define DFL_CRT_FILE2 ""
71#define DFL_KEY_FILE2 ""
Paul Bakkerfbb17802013-04-17 19:10:21 +020072#define DFL_PSK ""
73#define DFL_PSK_IDENTITY "Client_identity"
Paul Bakkerb60b95f2012-09-25 09:05:17 +000074#define DFL_FORCE_CIPHER 0
75#define DFL_RENEGOTIATION SSL_RENEGOTIATION_ENABLED
76#define DFL_ALLOW_LEGACY SSL_LEGACY_NO_RENEGOTIATION
Manuel Pégourié-Gonnard780d6712014-02-20 17:19:59 +010077#define DFL_RENEGOTIATE 0
Paul Bakker1d29fb52012-09-28 13:28:45 +000078#define DFL_MIN_VERSION -1
Paul Bakkerc1516be2013-06-29 16:01:32 +020079#define DFL_MAX_VERSION -1
Paul Bakker91ebfb52012-11-23 14:04:08 +010080#define DFL_AUTH_MODE SSL_VERIFY_OPTIONAL
Manuel Pégourié-Gonnard0c017a52013-07-18 14:07:36 +020081#define DFL_MFL_CODE SSL_MAX_FRAG_LEN_NONE
Manuel Pégourié-Gonnardaa0d4d12013-08-03 13:02:31 +020082#define DFL_TICKETS SSL_SESSION_TICKETS_ENABLED
Manuel Pégourié-Gonnarddbe1ee12014-02-21 09:18:13 +010083#define DFL_TICKET_TIMEOUT -1
Manuel Pégourié-Gonnard4c883452014-02-20 21:32:41 +010084#define DFL_CACHE_MAX -1
Manuel Pégourié-Gonnardc55a5b72014-02-20 22:50:56 +010085#define DFL_CACHE_TIMEOUT -1
Manuel Pégourié-Gonnard5d917ff2014-02-21 16:52:06 +010086#define DFL_SNI NULL
Paul Bakkerb60b95f2012-09-25 09:05:17 +000087
Manuel Pégourié-Gonnard0c017a52013-07-18 14:07:36 +020088#define LONG_RESPONSE "<p>01-blah-blah-blah-blah-blah-blah-blah-blah-blah\r\n" \
89 "02-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah\r\n" \
90 "03-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah\r\n" \
91 "04-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah\r\n" \
92 "05-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah\r\n" \
93 "06-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah\r\n" \
94 "07-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah</p>\r\n"
Manuel Pégourié-Gonnardbd7ce632013-07-17 15:34:17 +020095
Paul Bakker8e714d72013-07-18 11:05:13 +020096/* Uncomment LONG_RESPONSE at the end of HTTP_RESPONSE to test sending longer
97 * packets (for fragmentation purposes) */
Paul Bakkerb60b95f2012-09-25 09:05:17 +000098#define HTTP_RESPONSE \
99 "HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n" \
100 "<h2>PolarSSL Test Server</h2>\r\n" \
Manuel Pégourié-Gonnardbd7ce632013-07-17 15:34:17 +0200101 "<p>Successful connection using: %s</p>\r\n" // LONG_RESPONSE
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000102
103/*
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000104 * global options
105 */
106struct options
107{
Manuel Pégourié-Gonnard18d31f82013-12-13 16:21:41 +0100108 const char *server_addr; /* address on which the ssl service runs */
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000109 int server_port; /* port on which the ssl service runs */
110 int debug_level; /* level of debugging */
Paul Bakkeref3f8c72013-06-24 13:01:08 +0200111 const char *ca_file; /* the file with the CA certificate(s) */
112 const char *ca_path; /* the path with the CA certificate(s) reside */
Manuel Pégourié-Gonnard3ebb2cd2013-09-23 17:00:18 +0200113 const char *crt_file; /* the file with the server certificate */
114 const char *key_file; /* the file with the server key */
115 const char *crt_file2; /* the file with the 2nd server certificate */
116 const char *key_file2; /* the file with the 2nd server key */
Paul Bakkeref3f8c72013-06-24 13:01:08 +0200117 const char *psk; /* the pre-shared key */
118 const char *psk_identity; /* the pre-shared key identity */
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000119 int force_ciphersuite[2]; /* protocol/ciphersuite to use, or all */
120 int renegotiation; /* enable / disable renegotiation */
121 int allow_legacy; /* allow legacy renegotiation */
Manuel Pégourié-Gonnard780d6712014-02-20 17:19:59 +0100122 int renegotiate; /* attempt renegotiation? */
Paul Bakker1d29fb52012-09-28 13:28:45 +0000123 int min_version; /* minimum protocol version accepted */
Paul Bakkerc1516be2013-06-29 16:01:32 +0200124 int max_version; /* maximum protocol version accepted */
Paul Bakker91ebfb52012-11-23 14:04:08 +0100125 int auth_mode; /* verify mode for connection */
Manuel Pégourié-Gonnard0c017a52013-07-18 14:07:36 +0200126 unsigned char mfl_code; /* code for maximum fragment length */
Manuel Pégourié-Gonnardaa0d4d12013-08-03 13:02:31 +0200127 int tickets; /* enable / disable session tickets */
Manuel Pégourié-Gonnarddbe1ee12014-02-21 09:18:13 +0100128 int ticket_timeout; /* session ticket lifetime */
Manuel Pégourié-Gonnard4c883452014-02-20 21:32:41 +0100129 int cache_max; /* max number of session cache entries */
Manuel Pégourié-Gonnardc55a5b72014-02-20 22:50:56 +0100130 int cache_timeout; /* expiration delay of session cache entries */
Manuel Pégourié-Gonnard5d917ff2014-02-21 16:52:06 +0100131 char *sni; /* string decribing sni information */
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000132} opt;
133
Paul Bakker3c5ef712013-06-25 16:37:45 +0200134static void my_debug( void *ctx, int level, const char *str )
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000135{
136 if( level < opt.debug_level )
137 {
138 fprintf( (FILE *) ctx, "%s", str );
139 fflush( (FILE *) ctx );
140 }
141}
142
Manuel Pégourié-Gonnard3ebb2cd2013-09-23 17:00:18 +0200143
144#if defined(POLARSSL_X509_CRT_PARSE_C)
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000145#if defined(POLARSSL_FS_IO)
146#define USAGE_IO \
Paul Bakker1f9d02d2012-11-20 10:30:55 +0100147 " ca_file=%%s The single file containing the top-level CA(s) you fully trust\n" \
148 " default: \"\" (pre-loaded)\n" \
149 " ca_path=%%s The path containing the top-level CA(s) you fully trust\n" \
150 " default: \"\" (pre-loaded) (overrides ca_file)\n" \
151 " crt_file=%%s Your own cert and chain (in bottom to top order, top may be omitted)\n" \
Manuel Pégourié-Gonnardac8474f2013-09-25 11:35:15 +0200152 " default: see note after key_file2\n" \
153 " key_file=%%s default: see note after key_file2\n" \
Manuel Pégourié-Gonnard3ebb2cd2013-09-23 17:00:18 +0200154 " crt_file2=%%s Your second cert and chain (in bottom to top order, top may be omitted)\n" \
Manuel Pégourié-Gonnardac8474f2013-09-25 11:35:15 +0200155 " default: see note after key_file2\n" \
156 " key_file2=%%s default: see note below\n" \
157 " note: if neither crt_file/key_file nor crt_file2/key_file2 are used,\n" \
158 " preloaded certificate(s) and key(s) are used if available\n"
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000159#else
160#define USAGE_IO \
Paul Bakkered27a042013-04-18 22:46:23 +0200161 "\n" \
162 " No file operations available (POLARSSL_FS_IO not defined)\n" \
163 "\n"
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000164#endif /* POLARSSL_FS_IO */
Paul Bakkered27a042013-04-18 22:46:23 +0200165#else
166#define USAGE_IO ""
Paul Bakker36713e82013-09-17 13:25:29 +0200167#endif /* POLARSSL_X509_CRT_PARSE_C */
Paul Bakkered27a042013-04-18 22:46:23 +0200168
Manuel Pégourié-Gonnard8a3c64d2013-10-14 19:54:10 +0200169#if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED)
Paul Bakkered27a042013-04-18 22:46:23 +0200170#define USAGE_PSK \
171 " psk=%%s default: \"\" (in hex, without 0x)\n" \
172 " psk_identity=%%s default: \"Client_identity\"\n"
173#else
174#define USAGE_PSK ""
Manuel Pégourié-Gonnard8a3c64d2013-10-14 19:54:10 +0200175#endif /* POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED */
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000176
Paul Bakkera503a632013-08-14 13:48:06 +0200177#if defined(POLARSSL_SSL_SESSION_TICKETS)
178#define USAGE_TICKETS \
Manuel Pégourié-Gonnarddbe1ee12014-02-21 09:18:13 +0100179 " tickets=%%d default: 1 (enabled)\n" \
180 " ticket_timeout=%%d default: ticket default (1d)\n"
Paul Bakkera503a632013-08-14 13:48:06 +0200181#else
182#define USAGE_TICKETS ""
183#endif /* POLARSSL_SSL_SESSION_TICKETS */
184
Manuel Pégourié-Gonnard4c883452014-02-20 21:32:41 +0100185#if defined(POLARSSL_SSL_CACHE_C)
186#define USAGE_CACHE \
Manuel Pégourié-Gonnardc55a5b72014-02-20 22:50:56 +0100187 " cache_max=%%d default: cache default (50)\n" \
188 " cache_timeout=%%d default: cache default (1d)\n"
Manuel Pégourié-Gonnard4c883452014-02-20 21:32:41 +0100189#else
190#define USAGE_CACHE ""
191#endif /* POLARSSL_SSL_CACHE_C */
192
Manuel Pégourié-Gonnard5d917ff2014-02-21 16:52:06 +0100193#if defined(POLARSSL_SNI)
194#define USAGE_SNI \
195 " sni=%%s name1,cert1,key1[,name2,cert2,key2[,...]]\n" \
196 " default: disabled\n"
197#else
198#define USAGE_SNI ""
199#endif /* POLARSSL_SNI */
200
Paul Bakker05decb22013-08-15 13:33:48 +0200201#if defined(POLARSSL_SSL_MAX_FRAGMENT_LENGTH)
202#define USAGE_MAX_FRAG_LEN \
203 " max_frag_len=%%d default: 16384 (tls default)\n" \
204 " options: 512, 1024, 2048, 4096\n"
205#else
206#define USAGE_MAX_FRAG_LEN ""
207#endif /* POLARSSL_SSL_MAX_FRAGMENT_LENGTH */
208
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000209#define USAGE \
210 "\n usage: ssl_server2 param=<>...\n" \
211 "\n acceptable parameters:\n" \
Manuel Pégourié-Gonnard18d31f82013-12-13 16:21:41 +0100212 " server_addr=%%d default: (all interfaces)\n" \
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000213 " server_port=%%d default: 4433\n" \
214 " debug_level=%%d default: 0 (disabled)\n" \
Manuel Pégourié-Gonnard2fc243d2014-02-19 18:22:59 +0100215 "\n" \
216 " auth_mode=%%s default: \"optional\"\n" \
217 " options: none, optional, required\n" \
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000218 USAGE_IO \
Manuel Pégourié-Gonnard5d917ff2014-02-21 16:52:06 +0100219 USAGE_SNI \
Manuel Pégourié-Gonnard2fc243d2014-02-19 18:22:59 +0100220 "\n" \
221 USAGE_PSK \
222 "\n" \
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000223 " renegotiation=%%d default: 1 (enabled)\n" \
224 " allow_legacy=%%d default: 0 (disabled)\n" \
Manuel Pégourié-Gonnard780d6712014-02-20 17:19:59 +0100225 " renegotiate=%%d default: 0 (disabled)\n" \
Manuel Pégourié-Gonnard2fc243d2014-02-19 18:22:59 +0100226 USAGE_TICKETS \
Manuel Pégourié-Gonnardc55a5b72014-02-20 22:50:56 +0100227 USAGE_CACHE \
Manuel Pégourié-Gonnard2fc243d2014-02-19 18:22:59 +0100228 USAGE_MAX_FRAG_LEN \
229 "\n" \
Paul Bakker1d29fb52012-09-28 13:28:45 +0000230 " min_version=%%s default: \"ssl3\"\n" \
Paul Bakkerc1516be2013-06-29 16:01:32 +0200231 " max_version=%%s default: \"tls1_2\"\n" \
232 " force_version=%%s default: \"\" (none)\n" \
Paul Bakker1d29fb52012-09-28 13:28:45 +0000233 " options: ssl3, tls1, tls1_1, tls1_2\n" \
Paul Bakkerfbb17802013-04-17 19:10:21 +0200234 "\n" \
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000235 " force_ciphersuite=<name> default: all enabled\n"\
236 " acceptable ciphersuite names:\n"
237
Paul Bakkered27a042013-04-18 22:46:23 +0200238#if !defined(POLARSSL_ENTROPY_C) || \
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000239 !defined(POLARSSL_SSL_TLS_C) || !defined(POLARSSL_SSL_SRV_C) || \
Paul Bakkered27a042013-04-18 22:46:23 +0200240 !defined(POLARSSL_NET_C) || !defined(POLARSSL_CTR_DRBG_C)
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000241int main( int argc, char *argv[] )
242{
243 ((void) argc);
244 ((void) argv);
245
Paul Bakkered27a042013-04-18 22:46:23 +0200246 printf("POLARSSL_ENTROPY_C and/or "
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000247 "POLARSSL_SSL_TLS_C and/or POLARSSL_SSL_SRV_C and/or "
Paul Bakkered27a042013-04-18 22:46:23 +0200248 "POLARSSL_NET_C and/or POLARSSL_CTR_DRBG_C not defined.\n");
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000249 return( 0 );
250}
251#else
Manuel Pégourié-Gonnard5d917ff2014-02-21 16:52:06 +0100252
253#if defined(POLARSSL_SNI)
254typedef struct _sni_entry sni_entry;
255
256struct _sni_entry {
257 const char *name;
258 x509_crt *cert;
259 pk_context *key;
260 sni_entry *next;
261};
262
263/*
264 * Parse a string of triplets name1,crt1,key1[,name2,crt2,key2[,...]]
265 * into a usable sni_entry list.
266 *
267 * Note: this is not production quality: leaks memory if parsing fails,
268 * and error reporting is poor.
269 */
270sni_entry *sni_parse( char *sni_string )
271{
272 sni_entry *cur = NULL, *new = NULL;
273 char *p = sni_string;
274 char *end = p;
275 char *crt_file, *key_file;
276
277 while( *end != '\0' )
278 ++end;
279 *end = ',';
280
281 while( p <= end )
282 {
283 if( ( new = polarssl_malloc( sizeof( sni_entry ) ) ) == NULL )
284 return( NULL );
285
286 memset( new, 0, sizeof( sni_entry ) );
287
288 if( ( new->cert = polarssl_malloc( sizeof( x509_crt ) ) ) == NULL ||
289 ( new->key = polarssl_malloc( sizeof( pk_context ) ) ) == NULL )
290 return( NULL );
291
292 x509_crt_init( new->cert );
293 pk_init( new->key );
294
295 new->name = p;
296 while( *p != ',' ) if( ++p > end ) return( NULL );
297 *p++ = '\0';
298
299 crt_file = p;
300 while( *p != ',' ) if( ++p > end ) return( NULL );
301 *p++ = '\0';
302
303 key_file = p;
304 while( *p != ',' ) if( ++p > end ) return( NULL );
305 *p++ = '\0';
306
307 if( x509_crt_parse_file( new->cert, crt_file ) != 0 ||
308 pk_parse_keyfile( new->key, key_file, "" ) != 0 )
309 return( NULL );
310
311 new->next = cur;
312 cur = new;
313
314 }
315
316 return( cur );
317}
318
319void sni_free( sni_entry *head )
320{
321 sni_entry *cur = head, *next;
322
323 while( cur != NULL )
324 {
325 x509_crt_free( cur->cert );
326 polarssl_free( cur->cert );
327
328 pk_free( cur->key );
329 polarssl_free( cur->key );
330
331 next = cur->next;
332 polarssl_free( cur );
333 cur = next;
334 }
335}
336
337/*
338 * SNI callback.
339 */
340int sni_callback( void *p_info, ssl_context *ssl,
341 const unsigned char *name, size_t name_len )
342{
343 sni_entry *cur = (sni_entry *) p_info;
344
345 while( cur != NULL )
346 {
347 if( name_len == strlen( cur->name ) &&
348 memcmp( name, cur->name, name_len ) == 0 )
349 {
350 ssl_set_own_cert( ssl, cur->cert, cur->key );
351 return( 0 );
352 }
353
354 cur = cur->next;
355 }
356
357 return( -1 );
358}
359
360#endif /* POLARSSL_SNI */
361
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000362int main( int argc, char *argv[] )
363{
Manuel Pégourié-Gonnard0c017a52013-07-18 14:07:36 +0200364 int ret = 0, len, written, frags;
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000365 int listen_fd;
366 int client_fd = -1;
367 unsigned char buf[1024];
Manuel Pégourié-Gonnard8a3c64d2013-10-14 19:54:10 +0200368#if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED)
Paul Bakkerfbb17802013-04-17 19:10:21 +0200369 unsigned char psk[256];
370 size_t psk_len = 0;
Paul Bakkered27a042013-04-18 22:46:23 +0200371#endif
Paul Bakkeref3f8c72013-06-24 13:01:08 +0200372 const char *pers = "ssl_server2";
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000373
374 entropy_context entropy;
375 ctr_drbg_context ctr_drbg;
376 ssl_context ssl;
Paul Bakker36713e82013-09-17 13:25:29 +0200377#if defined(POLARSSL_X509_CRT_PARSE_C)
Paul Bakkerc559c7a2013-09-18 14:13:26 +0200378 x509_crt cacert;
379 x509_crt srvcert;
Manuel Pégourié-Gonnardac755232013-08-19 14:10:16 +0200380 pk_context pkey;
Manuel Pégourié-Gonnard3ebb2cd2013-09-23 17:00:18 +0200381 x509_crt srvcert2;
382 pk_context pkey2;
Manuel Pégourié-Gonnarda0fdf8b2013-09-25 14:05:49 +0200383 int key_cert_init = 0, key_cert_init2 = 0;
Paul Bakkered27a042013-04-18 22:46:23 +0200384#endif
Paul Bakker0a597072012-09-25 21:55:46 +0000385#if defined(POLARSSL_SSL_CACHE_C)
386 ssl_cache_context cache;
387#endif
Manuel Pégourié-Gonnard5d917ff2014-02-21 16:52:06 +0100388#if defined(POLARSSL_SNI)
389 sni_entry *sni_info = NULL;
390#endif
Paul Bakker82024bf2013-07-04 11:52:32 +0200391#if defined(POLARSSL_MEMORY_BUFFER_ALLOC_C)
392 unsigned char alloc_buf[100000];
393#endif
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000394
395 int i;
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000396 char *p, *q;
397 const int *list;
398
Paul Bakker82024bf2013-07-04 11:52:32 +0200399#if defined(POLARSSL_MEMORY_BUFFER_ALLOC_C)
400 memory_buffer_alloc_init( alloc_buf, sizeof(alloc_buf) );
401#endif
402
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000403 /*
Manuel Pégourié-Gonnard3bd2aae2013-09-20 13:10:13 +0200404 * Make sure memory references are valid in case we exit early.
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000405 */
406 listen_fd = 0;
Manuel Pégourié-Gonnard3bd2aae2013-09-20 13:10:13 +0200407 memset( &ssl, 0, sizeof( ssl_context ) );
Paul Bakker36713e82013-09-17 13:25:29 +0200408#if defined(POLARSSL_X509_CRT_PARSE_C)
Paul Bakker369d2eb2013-09-18 11:58:25 +0200409 x509_crt_init( &cacert );
410 x509_crt_init( &srvcert );
Manuel Pégourié-Gonnardac755232013-08-19 14:10:16 +0200411 pk_init( &pkey );
Manuel Pégourié-Gonnard3ebb2cd2013-09-23 17:00:18 +0200412 x509_crt_init( &srvcert2 );
413 pk_init( &pkey2 );
Paul Bakkered27a042013-04-18 22:46:23 +0200414#endif
Paul Bakker0a597072012-09-25 21:55:46 +0000415#if defined(POLARSSL_SSL_CACHE_C)
416 ssl_cache_init( &cache );
417#endif
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000418
419 if( argc == 0 )
420 {
421 usage:
422 if( ret == 0 )
423 ret = 1;
424
425 printf( USAGE );
426
427 list = ssl_list_ciphersuites();
428 while( *list )
429 {
Paul Bakkerbcbe2d82013-04-19 09:10:20 +0200430 printf(" %-42s", ssl_get_ciphersuite_name( *list ) );
Paul Bakkered27a042013-04-18 22:46:23 +0200431 list++;
432 if( !*list )
433 break;
434 printf(" %s\n", ssl_get_ciphersuite_name( *list ) );
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000435 list++;
436 }
437 printf("\n");
438 goto exit;
439 }
440
Manuel Pégourié-Gonnard18d31f82013-12-13 16:21:41 +0100441 opt.server_addr = DFL_SERVER_ADDR;
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000442 opt.server_port = DFL_SERVER_PORT;
443 opt.debug_level = DFL_DEBUG_LEVEL;
444 opt.ca_file = DFL_CA_FILE;
445 opt.ca_path = DFL_CA_PATH;
446 opt.crt_file = DFL_CRT_FILE;
447 opt.key_file = DFL_KEY_FILE;
Manuel Pégourié-Gonnard3ebb2cd2013-09-23 17:00:18 +0200448 opt.crt_file2 = DFL_CRT_FILE2;
449 opt.key_file2 = DFL_KEY_FILE2;
Paul Bakkerfbb17802013-04-17 19:10:21 +0200450 opt.psk = DFL_PSK;
451 opt.psk_identity = DFL_PSK_IDENTITY;
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000452 opt.force_ciphersuite[0]= DFL_FORCE_CIPHER;
453 opt.renegotiation = DFL_RENEGOTIATION;
454 opt.allow_legacy = DFL_ALLOW_LEGACY;
Manuel Pégourié-Gonnard780d6712014-02-20 17:19:59 +0100455 opt.renegotiate = DFL_RENEGOTIATE;
Paul Bakker1d29fb52012-09-28 13:28:45 +0000456 opt.min_version = DFL_MIN_VERSION;
Paul Bakkerc1516be2013-06-29 16:01:32 +0200457 opt.max_version = DFL_MAX_VERSION;
Paul Bakker91ebfb52012-11-23 14:04:08 +0100458 opt.auth_mode = DFL_AUTH_MODE;
Manuel Pégourié-Gonnard0c017a52013-07-18 14:07:36 +0200459 opt.mfl_code = DFL_MFL_CODE;
Manuel Pégourié-Gonnardaa0d4d12013-08-03 13:02:31 +0200460 opt.tickets = DFL_TICKETS;
Manuel Pégourié-Gonnarddbe1ee12014-02-21 09:18:13 +0100461 opt.ticket_timeout = DFL_TICKET_TIMEOUT;
Manuel Pégourié-Gonnard4c883452014-02-20 21:32:41 +0100462 opt.cache_max = DFL_CACHE_MAX;
Manuel Pégourié-Gonnardc55a5b72014-02-20 22:50:56 +0100463 opt.cache_timeout = DFL_CACHE_TIMEOUT;
Manuel Pégourié-Gonnard5d917ff2014-02-21 16:52:06 +0100464 opt.sni = DFL_SNI;
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000465
466 for( i = 1; i < argc; i++ )
467 {
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000468 p = argv[i];
469 if( ( q = strchr( p, '=' ) ) == NULL )
470 goto usage;
471 *q++ = '\0';
472
473 if( strcmp( p, "server_port" ) == 0 )
474 {
475 opt.server_port = atoi( q );
476 if( opt.server_port < 1 || opt.server_port > 65535 )
477 goto usage;
478 }
Manuel Pégourié-Gonnard18d31f82013-12-13 16:21:41 +0100479 else if( strcmp( p, "server_addr" ) == 0 )
480 opt.server_addr = q;
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000481 else if( strcmp( p, "debug_level" ) == 0 )
482 {
483 opt.debug_level = atoi( q );
484 if( opt.debug_level < 0 || opt.debug_level > 65535 )
485 goto usage;
486 }
487 else if( strcmp( p, "ca_file" ) == 0 )
488 opt.ca_file = q;
489 else if( strcmp( p, "ca_path" ) == 0 )
490 opt.ca_path = q;
491 else if( strcmp( p, "crt_file" ) == 0 )
492 opt.crt_file = q;
493 else if( strcmp( p, "key_file" ) == 0 )
494 opt.key_file = q;
Manuel Pégourié-Gonnard3ebb2cd2013-09-23 17:00:18 +0200495 else if( strcmp( p, "crt_file2" ) == 0 )
496 opt.crt_file2 = q;
497 else if( strcmp( p, "key_file2" ) == 0 )
498 opt.key_file2 = q;
Paul Bakkerfbb17802013-04-17 19:10:21 +0200499 else if( strcmp( p, "psk" ) == 0 )
500 opt.psk = q;
501 else if( strcmp( p, "psk_identity" ) == 0 )
502 opt.psk_identity = q;
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000503 else if( strcmp( p, "force_ciphersuite" ) == 0 )
504 {
505 opt.force_ciphersuite[0] = -1;
506
507 opt.force_ciphersuite[0] = ssl_get_ciphersuite_id( q );
508
509 if( opt.force_ciphersuite[0] <= 0 )
510 {
511 ret = 2;
512 goto usage;
513 }
514 opt.force_ciphersuite[1] = 0;
515 }
516 else if( strcmp( p, "renegotiation" ) == 0 )
517 {
518 opt.renegotiation = (atoi( q )) ? SSL_RENEGOTIATION_ENABLED :
519 SSL_RENEGOTIATION_DISABLED;
520 }
521 else if( strcmp( p, "allow_legacy" ) == 0 )
522 {
523 opt.allow_legacy = atoi( q );
524 if( opt.allow_legacy < 0 || opt.allow_legacy > 1 )
525 goto usage;
526 }
Manuel Pégourié-Gonnard780d6712014-02-20 17:19:59 +0100527 else if( strcmp( p, "renegotiate" ) == 0 )
528 {
529 opt.renegotiate = atoi( q );
530 if( opt.renegotiate < 0 || opt.renegotiate > 1 )
531 goto usage;
532 }
Paul Bakker1d29fb52012-09-28 13:28:45 +0000533 else if( strcmp( p, "min_version" ) == 0 )
534 {
535 if( strcmp( q, "ssl3" ) == 0 )
536 opt.min_version = SSL_MINOR_VERSION_0;
537 else if( strcmp( q, "tls1" ) == 0 )
538 opt.min_version = SSL_MINOR_VERSION_1;
539 else if( strcmp( q, "tls1_1" ) == 0 )
540 opt.min_version = SSL_MINOR_VERSION_2;
541 else if( strcmp( q, "tls1_2" ) == 0 )
542 opt.min_version = SSL_MINOR_VERSION_3;
543 else
544 goto usage;
545 }
Paul Bakkerc1516be2013-06-29 16:01:32 +0200546 else if( strcmp( p, "max_version" ) == 0 )
547 {
548 if( strcmp( q, "ssl3" ) == 0 )
549 opt.max_version = SSL_MINOR_VERSION_0;
550 else if( strcmp( q, "tls1" ) == 0 )
551 opt.max_version = SSL_MINOR_VERSION_1;
552 else if( strcmp( q, "tls1_1" ) == 0 )
553 opt.max_version = SSL_MINOR_VERSION_2;
554 else if( strcmp( q, "tls1_2" ) == 0 )
555 opt.max_version = SSL_MINOR_VERSION_3;
556 else
557 goto usage;
558 }
559 else if( strcmp( p, "force_version" ) == 0 )
560 {
561 if( strcmp( q, "ssl3" ) == 0 )
562 {
563 opt.min_version = SSL_MINOR_VERSION_0;
564 opt.max_version = SSL_MINOR_VERSION_0;
565 }
566 else if( strcmp( q, "tls1" ) == 0 )
567 {
568 opt.min_version = SSL_MINOR_VERSION_1;
569 opt.max_version = SSL_MINOR_VERSION_1;
570 }
571 else if( strcmp( q, "tls1_1" ) == 0 )
572 {
573 opt.min_version = SSL_MINOR_VERSION_2;
574 opt.max_version = SSL_MINOR_VERSION_2;
575 }
576 else if( strcmp( q, "tls1_2" ) == 0 )
577 {
578 opt.min_version = SSL_MINOR_VERSION_3;
579 opt.max_version = SSL_MINOR_VERSION_3;
580 }
581 else
582 goto usage;
583 }
Paul Bakker91ebfb52012-11-23 14:04:08 +0100584 else if( strcmp( p, "auth_mode" ) == 0 )
585 {
586 if( strcmp( q, "none" ) == 0 )
587 opt.auth_mode = SSL_VERIFY_NONE;
588 else if( strcmp( q, "optional" ) == 0 )
589 opt.auth_mode = SSL_VERIFY_OPTIONAL;
590 else if( strcmp( q, "required" ) == 0 )
591 opt.auth_mode = SSL_VERIFY_REQUIRED;
592 else
593 goto usage;
594 }
Manuel Pégourié-Gonnard0c017a52013-07-18 14:07:36 +0200595 else if( strcmp( p, "max_frag_len" ) == 0 )
596 {
597 if( strcmp( q, "512" ) == 0 )
598 opt.mfl_code = SSL_MAX_FRAG_LEN_512;
599 else if( strcmp( q, "1024" ) == 0 )
600 opt.mfl_code = SSL_MAX_FRAG_LEN_1024;
601 else if( strcmp( q, "2048" ) == 0 )
602 opt.mfl_code = SSL_MAX_FRAG_LEN_2048;
603 else if( strcmp( q, "4096" ) == 0 )
604 opt.mfl_code = SSL_MAX_FRAG_LEN_4096;
605 else
606 goto usage;
607 }
Manuel Pégourié-Gonnardaa0d4d12013-08-03 13:02:31 +0200608 else if( strcmp( p, "tickets" ) == 0 )
609 {
610 opt.tickets = atoi( q );
611 if( opt.tickets < 0 || opt.tickets > 1 )
612 goto usage;
613 }
Manuel Pégourié-Gonnarddbe1ee12014-02-21 09:18:13 +0100614 else if( strcmp( p, "ticket_timeout" ) == 0 )
615 {
616 opt.ticket_timeout = atoi( q );
617 if( opt.ticket_timeout < 0 )
618 goto usage;
619 }
Manuel Pégourié-Gonnard4c883452014-02-20 21:32:41 +0100620 else if( strcmp( p, "cache_max" ) == 0 )
621 {
622 opt.cache_max = atoi( q );
623 if( opt.cache_max < 0 )
624 goto usage;
625 }
Manuel Pégourié-Gonnardc55a5b72014-02-20 22:50:56 +0100626 else if( strcmp( p, "cache_timeout" ) == 0 )
627 {
628 opt.cache_timeout = atoi( q );
629 if( opt.cache_timeout < 0 )
630 goto usage;
631 }
Manuel Pégourié-Gonnard5d917ff2014-02-21 16:52:06 +0100632 else if( strcmp( p, "sni" ) == 0 )
633 {
634 opt.sni = q;
635 }
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000636 else
637 goto usage;
638 }
639
Paul Bakkerc1516be2013-06-29 16:01:32 +0200640 if( opt.force_ciphersuite[0] > 0 )
641 {
642 const ssl_ciphersuite_t *ciphersuite_info;
643 ciphersuite_info = ssl_ciphersuite_from_id( opt.force_ciphersuite[0] );
644
Paul Bakker5b55b792013-07-19 13:43:43 +0200645 if( opt.max_version != -1 &&
646 ciphersuite_info->min_minor_ver > opt.max_version )
647 {
648 printf("forced ciphersuite not allowed with this protocol version\n");
649 ret = 2;
650 goto usage;
651 }
652 if( opt.min_version != -1 &&
Paul Bakkerc1516be2013-06-29 16:01:32 +0200653 ciphersuite_info->max_minor_ver < opt.min_version )
654 {
655 printf("forced ciphersuite not allowed with this protocol version\n");
656 ret = 2;
657 goto usage;
658 }
Paul Bakker5b55b792013-07-19 13:43:43 +0200659 if( opt.max_version > ciphersuite_info->max_minor_ver )
660 opt.max_version = ciphersuite_info->max_minor_ver;
661 if( opt.min_version < ciphersuite_info->min_minor_ver )
662 opt.min_version = ciphersuite_info->min_minor_ver;
Paul Bakkerc1516be2013-06-29 16:01:32 +0200663 }
664
Manuel Pégourié-Gonnard8a3c64d2013-10-14 19:54:10 +0200665#if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED)
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000666 /*
Paul Bakkerfbb17802013-04-17 19:10:21 +0200667 * Unhexify the pre-shared key if any is given
668 */
669 if( strlen( opt.psk ) )
670 {
671 unsigned char c;
672 size_t j;
673
674 if( strlen( opt.psk ) % 2 != 0 )
675 {
676 printf("pre-shared key not valid hex\n");
677 goto exit;
678 }
679
680 psk_len = strlen( opt.psk ) / 2;
681
682 for( j = 0; j < strlen( opt.psk ); j += 2 )
683 {
684 c = opt.psk[j];
685 if( c >= '0' && c <= '9' )
686 c -= '0';
687 else if( c >= 'a' && c <= 'f' )
688 c -= 'a' - 10;
689 else if( c >= 'A' && c <= 'F' )
690 c -= 'A' - 10;
691 else
692 {
693 printf("pre-shared key not valid hex\n");
694 goto exit;
695 }
696 psk[ j / 2 ] = c << 4;
697
698 c = opt.psk[j + 1];
699 if( c >= '0' && c <= '9' )
700 c -= '0';
701 else if( c >= 'a' && c <= 'f' )
702 c -= 'a' - 10;
703 else if( c >= 'A' && c <= 'F' )
704 c -= 'A' - 10;
705 else
706 {
707 printf("pre-shared key not valid hex\n");
708 goto exit;
709 }
710 psk[ j / 2 ] |= c;
711 }
712 }
Manuel Pégourié-Gonnard8a3c64d2013-10-14 19:54:10 +0200713#endif /* POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED */
Paul Bakkerfbb17802013-04-17 19:10:21 +0200714
715 /*
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000716 * 0. Initialize the RNG and the session data
717 */
718 printf( "\n . Seeding the random number generator..." );
719 fflush( stdout );
720
721 entropy_init( &entropy );
722 if( ( ret = ctr_drbg_init( &ctr_drbg, entropy_func, &entropy,
Paul Bakkeref3f8c72013-06-24 13:01:08 +0200723 (const unsigned char *) pers,
724 strlen( pers ) ) ) != 0 )
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000725 {
726 printf( " failed\n ! ctr_drbg_init returned -0x%x\n", -ret );
727 goto exit;
728 }
729
730 printf( " ok\n" );
731
Paul Bakker36713e82013-09-17 13:25:29 +0200732#if defined(POLARSSL_X509_CRT_PARSE_C)
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000733 /*
734 * 1.1. Load the trusted CA
735 */
736 printf( " . Loading the CA root certificate ..." );
737 fflush( stdout );
738
739#if defined(POLARSSL_FS_IO)
740 if( strlen( opt.ca_path ) )
Paul Bakkerddf26b42013-09-18 13:46:23 +0200741 ret = x509_crt_parse_path( &cacert, opt.ca_path );
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000742 else if( strlen( opt.ca_file ) )
Paul Bakkerddf26b42013-09-18 13:46:23 +0200743 ret = x509_crt_parse_file( &cacert, opt.ca_file );
744 else
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000745#endif
746#if defined(POLARSSL_CERTS_C)
Manuel Pégourié-Gonnard641de712013-09-25 13:23:33 +0200747 ret = x509_crt_parse( &cacert, (const unsigned char *) test_ca_list,
748 strlen( test_ca_list ) );
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000749#else
750 {
751 ret = 1;
752 printf("POLARSSL_CERTS_C not defined.");
753 }
754#endif
755 if( ret < 0 )
756 {
Paul Bakkerddf26b42013-09-18 13:46:23 +0200757 printf( " failed\n ! x509_crt_parse returned -0x%x\n\n", -ret );
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000758 goto exit;
759 }
760
761 printf( " ok (%d skipped)\n", ret );
762
763 /*
764 * 1.2. Load own certificate and private key
765 */
766 printf( " . Loading the server cert. and key..." );
767 fflush( stdout );
768
Manuel Pégourié-Gonnardb095a7b2013-09-24 21:14:51 +0200769#if defined(POLARSSL_FS_IO)
770 if( strlen( opt.crt_file ) )
Manuel Pégourié-Gonnardb095a7b2013-09-24 21:14:51 +0200771 {
Manuel Pégourié-Gonnarda0fdf8b2013-09-25 14:05:49 +0200772 key_cert_init++;
Manuel Pégourié-Gonnardac8474f2013-09-25 11:35:15 +0200773 if( ( ret = x509_crt_parse_file( &srvcert, opt.crt_file ) ) != 0 )
774 {
775 printf( " failed\n ! x509_crt_parse_file returned -0x%x\n\n",
776 -ret );
777 goto exit;
778 }
Manuel Pégourié-Gonnardb095a7b2013-09-24 21:14:51 +0200779 }
Manuel Pégourié-Gonnardb095a7b2013-09-24 21:14:51 +0200780 if( strlen( opt.key_file ) )
Manuel Pégourié-Gonnardb095a7b2013-09-24 21:14:51 +0200781 {
Manuel Pégourié-Gonnarda0fdf8b2013-09-25 14:05:49 +0200782 key_cert_init++;
Manuel Pégourié-Gonnardac8474f2013-09-25 11:35:15 +0200783 if( ( ret = pk_parse_keyfile( &pkey, opt.key_file, "" ) ) != 0 )
784 {
785 printf( " failed\n ! pk_parse_keyfile returned -0x%x\n\n", -ret );
786 goto exit;
787 }
Manuel Pégourié-Gonnardb095a7b2013-09-24 21:14:51 +0200788 }
Manuel Pégourié-Gonnarda0fdf8b2013-09-25 14:05:49 +0200789 if( key_cert_init == 1 )
790 {
791 printf( " failed\n ! crt_file without key_file or vice-versa\n\n" );
792 goto exit;
793 }
794
Manuel Pégourié-Gonnardb095a7b2013-09-24 21:14:51 +0200795 if( strlen( opt.crt_file2 ) )
Manuel Pégourié-Gonnardb095a7b2013-09-24 21:14:51 +0200796 {
Manuel Pégourié-Gonnarda0fdf8b2013-09-25 14:05:49 +0200797 key_cert_init2++;
Manuel Pégourié-Gonnardac8474f2013-09-25 11:35:15 +0200798 if( ( ret = x509_crt_parse_file( &srvcert2, opt.crt_file2 ) ) != 0 )
799 {
800 printf( " failed\n ! x509_crt_parse_file(2) returned -0x%x\n\n",
801 -ret );
802 goto exit;
803 }
Manuel Pégourié-Gonnardb095a7b2013-09-24 21:14:51 +0200804 }
Manuel Pégourié-Gonnardb095a7b2013-09-24 21:14:51 +0200805 if( strlen( opt.key_file2 ) )
Manuel Pégourié-Gonnardb095a7b2013-09-24 21:14:51 +0200806 {
Manuel Pégourié-Gonnarda0fdf8b2013-09-25 14:05:49 +0200807 key_cert_init2++;
Manuel Pégourié-Gonnardac8474f2013-09-25 11:35:15 +0200808 if( ( ret = pk_parse_keyfile( &pkey2, opt.key_file2, "" ) ) != 0 )
809 {
810 printf( " failed\n ! pk_parse_keyfile(2) returned -0x%x\n\n",
811 -ret );
812 goto exit;
813 }
Manuel Pégourié-Gonnardb095a7b2013-09-24 21:14:51 +0200814 }
Manuel Pégourié-Gonnarda0fdf8b2013-09-25 14:05:49 +0200815 if( key_cert_init2 == 1 )
816 {
817 printf( " failed\n ! crt_file2 without key_file2 or vice-versa\n\n" );
818 goto exit;
819 }
Manuel Pégourié-Gonnardb095a7b2013-09-24 21:14:51 +0200820#endif
Manuel Pégourié-Gonnarda0fdf8b2013-09-25 14:05:49 +0200821 if( key_cert_init == 0 && key_cert_init2 == 0 )
Manuel Pégourié-Gonnardb095a7b2013-09-24 21:14:51 +0200822 {
Manuel Pégourié-Gonnardac8474f2013-09-25 11:35:15 +0200823#if !defined(POLARSSL_CERTS_C)
824 printf( "Not certificated or key provided, and \n"
825 "POLARSSL_CERTS_C not defined!\n" );
Manuel Pégourié-Gonnardb095a7b2013-09-24 21:14:51 +0200826 goto exit;
Manuel Pégourié-Gonnardac8474f2013-09-25 11:35:15 +0200827#else
Manuel Pégourié-Gonnarda0fdf8b2013-09-25 14:05:49 +0200828#if defined(POLARSSL_RSA_C)
Manuel Pégourié-Gonnardac8474f2013-09-25 11:35:15 +0200829 if( ( ret = x509_crt_parse( &srvcert,
Manuel Pégourié-Gonnarda0fdf8b2013-09-25 14:05:49 +0200830 (const unsigned char *) test_srv_crt_rsa,
831 strlen( test_srv_crt_rsa ) ) ) != 0 )
Manuel Pégourié-Gonnardac8474f2013-09-25 11:35:15 +0200832 {
833 printf( " failed\n ! x509_crt_parse returned -0x%x\n\n", -ret );
834 goto exit;
835 }
Manuel Pégourié-Gonnarda0fdf8b2013-09-25 14:05:49 +0200836 if( ( ret = pk_parse_key( &pkey,
837 (const unsigned char *) test_srv_key_rsa,
838 strlen( test_srv_key_rsa ), NULL, 0 ) ) != 0 )
Manuel Pégourié-Gonnardac8474f2013-09-25 11:35:15 +0200839 {
840 printf( " failed\n ! pk_parse_key returned -0x%x\n\n", -ret );
841 goto exit;
842 }
Manuel Pégourié-Gonnarda0fdf8b2013-09-25 14:05:49 +0200843 key_cert_init = 2;
844#endif /* POLARSSL_RSA_C */
845#if defined(POLARSSL_ECDSA_C)
Manuel Pégourié-Gonnardac8474f2013-09-25 11:35:15 +0200846 if( ( ret = x509_crt_parse( &srvcert2,
Manuel Pégourié-Gonnarda0fdf8b2013-09-25 14:05:49 +0200847 (const unsigned char *) test_srv_crt_ec,
848 strlen( test_srv_crt_ec ) ) ) != 0 )
Manuel Pégourié-Gonnardac8474f2013-09-25 11:35:15 +0200849 {
850 printf( " failed\n ! x509_crt_parse2 returned -0x%x\n\n", -ret );
851 goto exit;
852 }
Manuel Pégourié-Gonnarda0fdf8b2013-09-25 14:05:49 +0200853 if( ( ret = pk_parse_key( &pkey2,
854 (const unsigned char *) test_srv_key_ec,
855 strlen( test_srv_key_ec ), NULL, 0 ) ) != 0 )
Manuel Pégourié-Gonnardac8474f2013-09-25 11:35:15 +0200856 {
857 printf( " failed\n ! pk_parse_key2 returned -0x%x\n\n", -ret );
858 goto exit;
859 }
Manuel Pégourié-Gonnarda0fdf8b2013-09-25 14:05:49 +0200860 key_cert_init2 = 2;
861#endif /* POLARSSL_ECDSA_C */
Manuel Pégourié-Gonnardac8474f2013-09-25 11:35:15 +0200862#endif /* POLARSSL_CERTS_C */
863 }
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000864
865 printf( " ok\n" );
Paul Bakker36713e82013-09-17 13:25:29 +0200866#endif /* POLARSSL_X509_CRT_PARSE_C */
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000867
Manuel Pégourié-Gonnard5d917ff2014-02-21 16:52:06 +0100868#if defined(POLARSSL_SNI)
869 if( opt.sni != NULL )
870 {
871 printf( " . Setting up SNI information..." );
872 fflush( stdout );
873
874 if( ( sni_info = sni_parse( opt.sni ) ) == NULL )
875 {
876 printf( " failed\n" );
877 goto exit;
878 }
879
880 printf( " ok\n" );
881 }
882#endif /* POLARSSL_SNI */
883
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000884 /*
885 * 2. Setup the listening TCP socket
886 */
887 printf( " . Bind on tcp://localhost:%-4d/ ...", opt.server_port );
888 fflush( stdout );
889
Manuel Pégourié-Gonnard18d31f82013-12-13 16:21:41 +0100890 if( ( ret = net_bind( &listen_fd, opt.server_addr,
891 opt.server_port ) ) != 0 )
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000892 {
893 printf( " failed\n ! net_bind returned -0x%x\n\n", -ret );
894 goto exit;
895 }
896
897 printf( " ok\n" );
898
899 /*
900 * 3. Setup stuff
901 */
902 printf( " . Setting up the SSL/TLS structure..." );
903 fflush( stdout );
904
905 if( ( ret = ssl_init( &ssl ) ) != 0 )
906 {
907 printf( " failed\n ! ssl_init returned -0x%x\n\n", -ret );
908 goto exit;
909 }
910
911 ssl_set_endpoint( &ssl, SSL_IS_SERVER );
Paul Bakker91ebfb52012-11-23 14:04:08 +0100912 ssl_set_authmode( &ssl, opt.auth_mode );
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000913
Paul Bakker05decb22013-08-15 13:33:48 +0200914#if defined(POLARSSL_SSL_MAX_FRAGMENT_LENGTH)
Manuel Pégourié-Gonnard0c017a52013-07-18 14:07:36 +0200915 ssl_set_max_frag_len( &ssl, opt.mfl_code );
Paul Bakker05decb22013-08-15 13:33:48 +0200916#endif
Manuel Pégourié-Gonnard0c017a52013-07-18 14:07:36 +0200917
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000918 ssl_set_rng( &ssl, ctr_drbg_random, &ctr_drbg );
919 ssl_set_dbg( &ssl, my_debug, stdout );
920
Paul Bakker0a597072012-09-25 21:55:46 +0000921#if defined(POLARSSL_SSL_CACHE_C)
Manuel Pégourié-Gonnard4c883452014-02-20 21:32:41 +0100922 if( opt.cache_max != -1 )
923 ssl_cache_set_max_entries( &cache, opt.cache_max );
924
Manuel Pégourié-Gonnardc55a5b72014-02-20 22:50:56 +0100925 if( opt.cache_timeout != -1 )
926 ssl_cache_set_timeout( &cache, opt.cache_timeout );
927
Paul Bakker0a597072012-09-25 21:55:46 +0000928 ssl_set_session_cache( &ssl, ssl_cache_get, &cache,
929 ssl_cache_set, &cache );
930#endif
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000931
Paul Bakkera503a632013-08-14 13:48:06 +0200932#if defined(POLARSSL_SSL_SESSION_TICKETS)
Manuel Pégourié-Gonnardaa0d4d12013-08-03 13:02:31 +0200933 ssl_set_session_tickets( &ssl, opt.tickets );
Manuel Pégourié-Gonnarddbe1ee12014-02-21 09:18:13 +0100934
935 if( opt.ticket_timeout != -1 )
936 ssl_set_session_ticket_lifetime( &ssl, opt.ticket_timeout );
Paul Bakkera503a632013-08-14 13:48:06 +0200937#endif
Manuel Pégourié-Gonnardaa0d4d12013-08-03 13:02:31 +0200938
Paul Bakker41c83d32013-03-20 14:39:14 +0100939 if( opt.force_ciphersuite[0] != DFL_FORCE_CIPHER )
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000940 ssl_set_ciphersuites( &ssl, opt.force_ciphersuite );
941
942 ssl_set_renegotiation( &ssl, opt.renegotiation );
943 ssl_legacy_renegotiation( &ssl, opt.allow_legacy );
944
Paul Bakker36713e82013-09-17 13:25:29 +0200945#if defined(POLARSSL_X509_CRT_PARSE_C)
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000946 ssl_set_ca_chain( &ssl, &cacert, NULL, NULL );
Manuel Pégourié-Gonnarda0fdf8b2013-09-25 14:05:49 +0200947 if( key_cert_init )
948 ssl_set_own_cert( &ssl, &srvcert, &pkey );
949 if( key_cert_init2 )
950 ssl_set_own_cert( &ssl, &srvcert2, &pkey2 );
Manuel Pégourié-Gonnardb095a7b2013-09-24 21:14:51 +0200951#endif
Paul Bakkered27a042013-04-18 22:46:23 +0200952
Manuel Pégourié-Gonnard5d917ff2014-02-21 16:52:06 +0100953#if defined(POLARSSL_SNI)
954 if( opt.sni != NULL )
955 ssl_set_sni( &ssl, sni_callback, sni_info );
956#endif
957
Manuel Pégourié-Gonnard8a3c64d2013-10-14 19:54:10 +0200958#if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED)
Paul Bakker3c5ef712013-06-25 16:37:45 +0200959 ssl_set_psk( &ssl, psk, psk_len, (const unsigned char *) opt.psk_identity,
Paul Bakkerfbb17802013-04-17 19:10:21 +0200960 strlen( opt.psk_identity ) );
Paul Bakkered27a042013-04-18 22:46:23 +0200961#endif
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000962
963#if defined(POLARSSL_DHM_C)
Paul Bakker5d19f862012-09-28 07:33:00 +0000964 /*
965 * Use different group than default DHM group
966 */
Paul Bakkerd4324102012-09-26 08:29:38 +0000967 ssl_set_dh_param( &ssl, POLARSSL_DHM_RFC5114_MODP_2048_P,
968 POLARSSL_DHM_RFC5114_MODP_2048_G );
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000969#endif
970
Paul Bakker1d29fb52012-09-28 13:28:45 +0000971 if( opt.min_version != -1 )
972 ssl_set_min_version( &ssl, SSL_MAJOR_VERSION_3, opt.min_version );
973
Paul Bakkerc1516be2013-06-29 16:01:32 +0200974 if( opt.max_version != -1 )
975 ssl_set_max_version( &ssl, SSL_MAJOR_VERSION_3, opt.max_version );
976
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000977 printf( " ok\n" );
978
979reset:
980#ifdef POLARSSL_ERROR_C
981 if( ret != 0 )
982 {
983 char error_buf[100];
Paul Bakker03a8a792013-06-30 12:18:08 +0200984 polarssl_strerror( ret, error_buf, 100 );
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000985 printf("Last error was: %d - %s\n\n", ret, error_buf );
986 }
987#endif
988
989 if( client_fd != -1 )
990 net_close( client_fd );
991
992 ssl_session_reset( &ssl );
993
994 /*
995 * 3. Wait until a client connects
996 */
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000997 client_fd = -1;
998
999 printf( " . Waiting for a remote connection ..." );
1000 fflush( stdout );
1001
1002 if( ( ret = net_accept( listen_fd, &client_fd, NULL ) ) != 0 )
1003 {
1004 printf( " failed\n ! net_accept returned -0x%x\n\n", -ret );
1005 goto exit;
1006 }
1007
1008 ssl_set_bio( &ssl, net_recv, &client_fd,
1009 net_send, &client_fd );
1010
1011 printf( " ok\n" );
1012
1013 /*
1014 * 4. Handshake
1015 */
1016 printf( " . Performing the SSL/TLS handshake..." );
1017 fflush( stdout );
1018
1019 while( ( ret = ssl_handshake( &ssl ) ) != 0 )
1020 {
1021 if( ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE )
1022 {
1023 printf( " failed\n ! ssl_handshake returned -0x%x\n\n", -ret );
Paul Bakker1d29fb52012-09-28 13:28:45 +00001024 goto reset;
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001025 }
1026 }
1027
Manuel Pégourié-Gonnardc580a002014-02-12 10:15:30 +01001028 printf( " ok\n [ Protocol is %s ]\n [ Ciphersuite is %s ]\n",
1029 ssl_get_version( &ssl ), ssl_get_ciphersuite( &ssl ) );
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001030
Paul Bakker36713e82013-09-17 13:25:29 +02001031#if defined(POLARSSL_X509_CRT_PARSE_C)
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001032 /*
1033 * 5. Verify the server certificate
1034 */
1035 printf( " . Verifying peer X.509 certificate..." );
1036
1037 if( ( ret = ssl_get_verify_result( &ssl ) ) != 0 )
1038 {
1039 printf( " failed\n" );
1040
Paul Bakkerb0550d92012-10-30 07:51:03 +00001041 if( !ssl_get_peer_cert( &ssl ) )
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001042 printf( " ! no client certificate sent\n" );
1043
1044 if( ( ret & BADCERT_EXPIRED ) != 0 )
1045 printf( " ! client certificate has expired\n" );
1046
1047 if( ( ret & BADCERT_REVOKED ) != 0 )
1048 printf( " ! client certificate has been revoked\n" );
1049
1050 if( ( ret & BADCERT_NOT_TRUSTED ) != 0 )
1051 printf( " ! self-signed or not signed by a trusted CA\n" );
1052
1053 printf( "\n" );
1054 }
1055 else
1056 printf( " ok\n" );
1057
Paul Bakkerb0550d92012-10-30 07:51:03 +00001058 if( ssl_get_peer_cert( &ssl ) )
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001059 {
1060 printf( " . Peer certificate information ...\n" );
Paul Bakkerddf26b42013-09-18 13:46:23 +02001061 x509_crt_info( (char *) buf, sizeof( buf ) - 1, " ",
1062 ssl_get_peer_cert( &ssl ) );
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001063 printf( "%s\n", buf );
1064 }
Paul Bakker36713e82013-09-17 13:25:29 +02001065#endif /* POLARSSL_X509_CRT_PARSE_C */
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001066
1067 /*
1068 * 6. Read the HTTP Request
1069 */
1070 printf( " < Read from client:" );
1071 fflush( stdout );
1072
1073 do
1074 {
1075 len = sizeof( buf ) - 1;
1076 memset( buf, 0, sizeof( buf ) );
1077 ret = ssl_read( &ssl, buf, len );
1078
1079 if( ret == POLARSSL_ERR_NET_WANT_READ || ret == POLARSSL_ERR_NET_WANT_WRITE )
1080 continue;
1081
1082 if( ret <= 0 )
1083 {
1084 switch( ret )
1085 {
1086 case POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY:
1087 printf( " connection was closed gracefully\n" );
1088 break;
1089
1090 case POLARSSL_ERR_NET_CONN_RESET:
1091 printf( " connection was reset by peer\n" );
1092 break;
1093
1094 default:
1095 printf( " ssl_read returned -0x%x\n", -ret );
1096 break;
1097 }
1098
1099 break;
1100 }
1101
1102 len = ret;
Manuel Pégourié-Gonnardbd7ce632013-07-17 15:34:17 +02001103 printf( " %d bytes read\n\n%s\n", len, (char *) buf );
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001104
Paul Bakker82024bf2013-07-04 11:52:32 +02001105 if( memcmp( buf, "SERVERQUIT", 10 ) == 0 )
Manuel Pégourié-Gonnarde8ea0c02013-09-07 17:09:14 +02001106 {
1107 ret = 0;
Paul Bakker82024bf2013-07-04 11:52:32 +02001108 goto exit;
Manuel Pégourié-Gonnarde8ea0c02013-09-07 17:09:14 +02001109 }
Paul Bakker82024bf2013-07-04 11:52:32 +02001110
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001111 if( ret > 0 )
1112 break;
1113 }
1114 while( 1 );
1115
1116 /*
1117 * 7. Write the 200 Response
1118 */
1119 printf( " > Write to client:" );
1120 fflush( stdout );
1121
1122 len = sprintf( (char *) buf, HTTP_RESPONSE,
1123 ssl_get_ciphersuite( &ssl ) );
1124
Manuel Pégourié-Gonnard0c017a52013-07-18 14:07:36 +02001125 for( written = 0, frags = 0; written < len; written += ret, frags++ )
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001126 {
Manuel Pégourié-Gonnardbd7ce632013-07-17 15:34:17 +02001127 while( ( ret = ssl_write( &ssl, buf + written, len - written ) ) <= 0 )
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001128 {
Manuel Pégourié-Gonnardbd7ce632013-07-17 15:34:17 +02001129 if( ret == POLARSSL_ERR_NET_CONN_RESET )
1130 {
1131 printf( " failed\n ! peer closed the connection\n\n" );
1132 goto reset;
1133 }
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001134
Manuel Pégourié-Gonnardbd7ce632013-07-17 15:34:17 +02001135 if( ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE )
1136 {
1137 printf( " failed\n ! ssl_write returned %d\n\n", ret );
1138 goto exit;
1139 }
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001140 }
1141 }
1142
Manuel Pégourié-Gonnardbd7ce632013-07-17 15:34:17 +02001143 buf[written] = '\0';
Manuel Pégourié-Gonnard0c017a52013-07-18 14:07:36 +02001144 printf( " %d bytes written in %d fragments\n\n%s\n", written, frags, (char *) buf );
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001145
Manuel Pégourié-Gonnard780d6712014-02-20 17:19:59 +01001146 if( opt.renegotiate )
Manuel Pégourié-Gonnardf3dc2f62013-10-29 18:17:41 +01001147 {
Manuel Pégourié-Gonnard780d6712014-02-20 17:19:59 +01001148 /*
1149 * Request renegotiation (this must be done when the client is still
1150 * waiting for input from our side).
1151 */
1152 printf( " . Requestion renegotiation..." );
1153 fflush( stdout );
1154 while( ( ret = ssl_renegotiate( &ssl ) ) != 0 )
Manuel Pégourié-Gonnardf3dc2f62013-10-29 18:17:41 +01001155 {
Manuel Pégourié-Gonnard780d6712014-02-20 17:19:59 +01001156 if( ret != POLARSSL_ERR_NET_WANT_READ &&
1157 ret != POLARSSL_ERR_NET_WANT_WRITE )
1158 {
1159 printf( " failed\n ! ssl_renegotiate returned %d\n\n", ret );
Manuel Pégourié-Gonnard6d8404d2013-10-30 16:41:45 +01001160 goto exit;
Manuel Pégourié-Gonnard780d6712014-02-20 17:19:59 +01001161 }
Manuel Pégourié-Gonnardf3dc2f62013-10-29 18:17:41 +01001162 }
Manuel Pégourié-Gonnardf3dc2f62013-10-29 18:17:41 +01001163
Manuel Pégourié-Gonnard780d6712014-02-20 17:19:59 +01001164 /*
1165 * Should be a while loop, not an if, but here we're not actually
1166 * expecting data from the client, and since we're running tests
1167 * locally, we can just hope the handshake will finish the during the
1168 * first call.
1169 */
1170 if( ( ret = ssl_read( &ssl, buf, 0 ) ) != 0 )
1171 {
1172 if( ret != POLARSSL_ERR_NET_WANT_READ &&
1173 ret != POLARSSL_ERR_NET_WANT_WRITE )
1174 {
1175 printf( " failed\n ! ssl_read returned %d\n\n", ret );
1176
1177 /* Unexpected message probably means client didn't renegotiate
1178 * as requested */
1179 if( ret == POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE )
1180 goto reset;
1181 else
1182 goto exit;
1183 }
1184 }
1185
1186 printf( " ok\n" );
1187 }
Manuel Pégourié-Gonnardf3dc2f62013-10-29 18:17:41 +01001188
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001189 ret = 0;
1190 goto reset;
1191
1192exit:
1193
1194#ifdef POLARSSL_ERROR_C
1195 if( ret != 0 )
1196 {
1197 char error_buf[100];
Paul Bakker03a8a792013-06-30 12:18:08 +02001198 polarssl_strerror( ret, error_buf, 100 );
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001199 printf("Last error was: -0x%X - %s\n\n", -ret, error_buf );
1200 }
1201#endif
1202
1203 net_close( client_fd );
Paul Bakker36713e82013-09-17 13:25:29 +02001204#if defined(POLARSSL_X509_CRT_PARSE_C)
Paul Bakker36713e82013-09-17 13:25:29 +02001205 x509_crt_free( &cacert );
Manuel Pégourié-Gonnard3ebb2cd2013-09-23 17:00:18 +02001206 x509_crt_free( &srvcert );
Manuel Pégourié-Gonnardac755232013-08-19 14:10:16 +02001207 pk_free( &pkey );
Manuel Pégourié-Gonnard3ebb2cd2013-09-23 17:00:18 +02001208 x509_crt_free( &srvcert2 );
1209 pk_free( &pkey2 );
Paul Bakkered27a042013-04-18 22:46:23 +02001210#endif
Manuel Pégourié-Gonnard5d917ff2014-02-21 16:52:06 +01001211#if defined(POLARSSL_SNI)
1212 sni_free( sni_info );
1213#endif
Paul Bakkered27a042013-04-18 22:46:23 +02001214
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001215 ssl_free( &ssl );
Paul Bakker1ffefac2013-09-28 15:23:03 +02001216 entropy_free( &entropy );
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001217
Paul Bakker0a597072012-09-25 21:55:46 +00001218#if defined(POLARSSL_SSL_CACHE_C)
1219 ssl_cache_free( &cache );
1220#endif
1221
Paul Bakker1337aff2013-09-29 14:45:34 +02001222#if defined(POLARSSL_MEMORY_BUFFER_ALLOC_C)
1223#if defined(POLARSSL_MEMORY_DEBUG)
Paul Bakker82024bf2013-07-04 11:52:32 +02001224 memory_buffer_alloc_status();
1225#endif
Paul Bakker1337aff2013-09-29 14:45:34 +02001226 memory_buffer_alloc_free();
1227#endif
Paul Bakker82024bf2013-07-04 11:52:32 +02001228
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001229#if defined(_WIN32)
1230 printf( " + Press Enter to exit this program.\n" );
1231 fflush( stdout ); getchar();
1232#endif
1233
Paul Bakkerdbd79ca2013-07-24 16:28:35 +02001234 // Shell can not handle large exit numbers -> 1 for errors
1235 if( ret < 0 )
1236 ret = 1;
1237
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001238 return( ret );
1239}
1240#endif /* POLARSSL_BIGNUM_C && POLARSSL_ENTROPY_C && POLARSSL_SSL_TLS_C &&
1241 POLARSSL_SSL_SRV_C && POLARSSL_NET_C && POLARSSL_RSA_C &&
1242 POLARSSL_CTR_DRBG_C */